This is the 28th day of my participation in the First Challenge 2022.
Hello ~ I’m Milo! I am building an open source interface testing platform from 0 to 1, and also writing a set of corresponding tutorials, I hope you can support more. Welcome to follow my public account Milo test diary, get the latest article tutorial!
review
In the last section we wrote code for multi-environment configurations, and I’m sure you already know how to deploy multi-environment code.
This time we’re going to adjust the ugly desk.
You can see that the content is very vague, as a home page, really a bit shabby. Since it is our face, of course, we can’t continue to make it ugly. So we’re going to clean it up a little bit.
reference
While we’re at a loss, let’s take a look at some of the professional platforms. For example, antD Pro’s workbench, let’s see what we can learn from it.
We can draw lessons from the above three parts with red lines, which can be summarized as follows:
-
Quick navigation
-
The user list is used to view the user’s ranking and so on
-
project
In this project, we will take the test plan as the dimension to reflect the data of each test plan. What does that mean? When we think some core test set is worth looking at, we can look at it and the workbench will give us the most intuitive data, such as the pass rate.
Then, without further ado, sugarcane! Let’s take it one at a time.
No part of
We need three pieces of data, which projects the user participated in/how many cases the user created/how many people total.
- App/crud/project/ProjectDao. Add the following method in py
@staticmethod
async def query_user_project(user_id: int) - >int:
""" Created by Woody at 2022-02-13 12:05 query user number of projects :param user_id: user ID :return: return number of projects ""
ans = set(a)async with async_session() as session:
async with session.begin():
Select the user that has not been deleted
project_sql = select(Project).where(Project.deleted_at == 0)
projects = await session.execute(project_sql)
project_list = []
Place owner equal to the user in the list
for r in projects.scalars().all():
project_list.append(r.id)
if r.owner == user_id:
ans.add(r.id)
Add the project ID of the role to the list
# set = set
query = await session.execute(
select(ProjectRole).where(ProjectRole.deleted_at == 0, ProjectRole.user_id == user_id))
for q in query.scalars().all():
ans.add(q.project_id)
return len(ans)
Copy the code
How many items does a user have? There are two cases:
- How many projects are owned by him
- How many users are he in the project role list, and how many are he in the project role list
Because my SQL is really not good, so I used the form of code to write directly.
So we can figure out which project ids the user is in.
- New query user ranking method in app/crud/ test_Case/testCasedao.py
@staticmethod
@RedisHelper.cache("rank")
async def query_user_case_list() - >Dict[str.List] :
""" Created by Woody at 2022-10-13 12:59 query user case count and rank :return: ""
ans = dict(a)async with async_session() as session:
async with session.begin():
sql = select(TestCase.create_user, func.count(TestCase.id)) \
.outerjoin(User, and_(User.deleted_at == 0, TestCase.create_user == User.id)).where(
TestCase.deleted_at == 0).group_by(TestCase.create_user).order_by(
desc(func.count(TestCase.id)))
query = await session.execute(sql)
for i, q in enumerate(query.all()):
user, count = q
ans[str(user)] = [count, i + 1]
return ans
Copy the code
This operation is to query how many use cases the user has, and sort the user by the number of cases, the last ANS stores a mapping, userID => number of use cases and ranking.
Since this data is high-frequency data, we put it in Redis with an expiration time of about 30 seconds. (The number of new cases will be affected later, so you have to delete the cache.)
Write the app/routers/workspace/workspace. Py
from fastapi import APIRouter, Depends
from app.crud.project.ProjectDao import ProjectDao
from app.crud.test_case.TestCaseDao import TestCaseDao
from app.handler.fatcory import PityResponse
from app.routers import Permission
router = APIRouter(prefix="/workspace")
@router.get("/", description="Get Workbench user statistics")
async def query_user_statistics(user_info=Depends(Permission())) :
user_id = user_info['id']
count = await ProjectDao.query_user_project(user_id)
rank = await TestCaseDao.query_user_case_list()
case_count, user_rank = rank[str(user_id)]
return PityResponse.success(dict(project_count=count, case_count=case_count,
user_rank=user_rank, total_user=len(rank)))
Copy the code
Modify the page
Write a new component that reads this data from the interface, I won’t show you the details, and then passes it to the extraContent of the PageContainer component.
Look at the results:
Quick navigation
Quick navigation is a practical function. Generally speaking, it is convenient for users to customize it. However, in order to save time, we only complete the fixed link part first.
Define a tag component:
Write common components:
Actual effect:
Test plan data presentation
Due to space, we will not go into details, the general idea:
- Add a test plan relational table to store
Users of xx
Pay attention to theTest plan ID
- Make a few changes on the test plan page
Focus on
andTake off
The test plan - The most recent execution statistics for the test plan in question are displayed on the workbench front page
These contents are done after almost, I believe that can follow the friends here can also rely on their own to complete these contents. The code will continue to be posted to Github, so you can help yourself.
experience
Talk about my feelings, the benefits of writing things is convenient, but in fact, there are a lot of things to say, write more will be very wordy. However, video or other methods are difficult to grasp the main point, so the text tutorial of this project is nearing the end.
The future will optimize the code, rich documentation, more user-friendly. If you continue to give a text tutorial, not particularly detailed, is generally the idea of adding core code. (The quality of writing is also one aspect of it =.=)