Python The actual combat community
Java The actual combat community
Long press to identify the QR code below , Add as needed
Scan code, pay attention to add customer service
Into the Python community ▲
Scan code, pay attention to add customer service
Into the Java community ▲
author ：NathanSun, iOS developer , Currently working in the byte beat music team
This session The title of the title is very interesting , Compilation meeting “ Failure ” Test of . In general , Engineers want to write the test code , All the way “ A green light ” All pass , And then I'm glad how awesome the code I've written . But really good test code is able to capture the potential bug Test code , That is, it will make the test “ Failure ” Code for . Please pay attention to this session The main content of this article is UI test , But the same applies to unit testing .
Test cases can be local Xcode run , It can also be in CI Running on the machine . If in CI If you run , The test results will be in result bundle Inside , Then we can according to test bundle Printed information analysis test results . Good test code , Should be able to help fast read positioning problems , And more robust , This session I'll tell you how to do these two things . We know , Testing is generally divided into three steps ,set up, test, tear down. The second step test It can be divided into two sub steps , Behavior （actions） And assertions （assertions）, This session This is the framework of how to write good test code .
First step Set up
Xcode 11.4 Added a new API setUpWithError() throws. Suggest using before setUp() All of my classmates moved to this new one API, If setUp Process error , This API You can throw an exception and terminate the test prematurely .
In this method, you usually need to reset app state , For example, the last test permission opened the application permission , Here you can. reset Application permission . It is generally recommended to set continueAfterFailure = false, This stops testing immediately after failure , Make sure to stop immediately after the first error , Avoid multiple errors mixed together to cause difficulties in troubleshooting . Finally, this method needs to be run app.launch() start-up app, start-up app You can also add startup parameters or environment variables before , for example app.launchArguments.append('"-recipes-tests"). The main purpose of adding startup parameters or environment variables is to speed up your testing process , For example, you need to skip two steps of validation , Or your app There are four tab, And you need to jump straight to the fourth tab Test the relevant scenarios . This way you can quickly get to your test scenario , It can also avoid the test failure in other pre scenarios and affect your test .
The second step Test
Testing is nothing more than triggering an action , And judge by assertion that this behavior brings expected results .
It's important to name the test method , Generally, you have to figure out what your test goal is , And then name it for that purpose . For example, you're testing a recipe APP Inside Ingredients The correctness of the list , So you can name the test method testIngredientsListAccuracy. The following is the specific content of this test method , Testing is APP There's a list of milkshakes , Select a category , You can see the raw material details page corresponding to this category .
In the actual process of writing test behavior code , To sum up, here are some tips ：
The same UI How to do if your name changes all the time ？ It can be used enum To solve , Convert a string to enum In the form of , So if Label The name has changed , Only need to enum Corresponding string The value can be changed directly .
Package repeated code in multiple tests as helper function.
Organize the test code in an object-oriented way , Write the test code in a readable form , such as app.smoothieList().select(smoothie: .berryblue) You can see at a glance that what you want to do is to click on an element from the list .
As the test code gets bigger and bigger , Some test code can be managed in the same way as product code , For example, packaging into framework Or is it Swift package, This allows you to share test code across multiple projects .
Assertion is to judge whether the result meets the expectation , When using assertions, you need to pay attention to the following .
Don't neglect XCTAssert The optional variables in it message The role of . Tests are more often run in CI On the machine , So the more context information there is, the more helpful it will be to the location problem . such as XCTAsssertEqual(count, expectedCount), This is a bad way to write , Completely missing context information , A better way to write it is as shown in the figure below , Add contextual information to message Inside . Many projects use automated tools to collect and summarize these test results , Therefore, it is generally recommended not to include a specific file name path in the context information 、 Time stamps, etc , It's just leaving some general information , This ensures that the same errors can be aggregated .
Choose the most appropriate one according to the actual situation Assert sentence , It can get twice the result with half the effort . Consider using in Xcode 12.0 in , Newly added XCTIssue. About this API Details of , Please refer to this session.
Handle asynchronous test tasks , For example, click on a button Get network data , Wait for the network data to return and check the results . There are several ways ： The first is sleep Blind waiting for a while . Another way is to use waitForExistence(timeout: 5), This will use polling to check the results , It will be more efficient . The second method is recommended .
Explain optional It is best to XCTUnwrap. for instance ,favorites It's a optional, It can be used try XCTUnwrap(favorites, "favorites is nil, so there is nothing to count"), So if favorites It's a nil value , It throws an exception , The test program won't crash and tear down Can carry on .
If you're using test code from a common library , You can throw exceptions from a common library , And print out enough information , It's convenient to check the problem .
More use XCTContext.runActivity(named:, block:) Describe the context of the test , It can also be in context Inside plus XCTAttachment, Such as file 、 data 、 Picture information, etc .
Make good use of XCTSkipUnless, XCTSkipIf Skip some tests , This is Xcode 11.4 Start offering API. such , The test results report will be marked to remind which test processes are temporarily skipped , In the future, you won't forget that you need to add these features . Generally used in the following scenarios .
Skip irrelevant platforms or system versions
Skip new test code that hasn't been implemented yet
Tests that can't be fixed right now bug
Finally, let's take a look at tear down
About tear down, There are three suggestions .
Use XCode 11.4 What's new API,func tearDownWithError() throws.
stay tear down Method with some extra logs , It can also provide some simple analysis of failure results .
Can be reset setup Some of the settings in the process , Avoid interference with the next test .
Programmer column Scan code and pay attention to customer service Press and hold to recognize the QR code below to enter the group
Recent highlights are recommended ：
Here's a look Good articles to share with more people ↓↓