2. Write and execute Unit Tests
This section mainly includes two aspects. How to compile nunit TestCode(Format of the test code) and basic principles of the test (content of the test code ).
2.1. Use nunit
2.1.1. Build unit test
The test code must do the following:
1. Prepare the conditions required for the test
2. Call the method to be tested
3. Verify that the behavior of the method under test is consistent with the expected behavior
4. Clear various resources after completion
To use the nunit framework, you need to do the following:
1. Use the using declaration to reference the necessary nunit class (and add a reference pointing to nunitdll)
2. Define a test class, which must be public, replace a public constructor without parameters, and add the [testfixture] attribute mark to the class definition.
3. The test class contains methods marked with [test] attribute.
2.1.2. useful features
When using the nunit framework, in addition to the [testfixture] and [test] features mentioned above, there are also some useful features. Flexible use of these features will help improve the efficiency of testing code development. For details about the features and their functions, see Table 2.1 (nunit features ).
Table 2.1 features of nuint
1. Per-method setup and teardown
[Setup]: Use the method specified by this attribute to establish the environment. nunit calls the method marked by this feature before calling each [test] method.
[Teardown] is the same as [setup], but the call time is used for Environment Cleaning after each [test] method is completed.
2. Per-class setup and per-class teardown
The [testfixturesetup] and [testfixtureteardown] features are similar to the [setup] and [teardown] mentioned above, but they act on the entire [testfixture] class. You can use these two feature markup methods to set and clean up the entire test class environment.
3. Use categories for classification
[Category ("category name")] specifies the "type" of a test method ". After you use this feature to classify each test method, you can specify the type to be executed in the nunit environment.
You can write this feature together with the [test] feature, for example:
[Test, category ("test_0001")]
You can also separate two rows:
[Test]
[Category ("test_0001")]
Category also has an explicit property that can explicitly exclude the running of the category (unless specified in nunit GUI), as follows:
[Category ("test_0001", explicit = true)]
4. Expected exception: expectedexception
There are two exceptions for testing:
Exception thrown from test code
Exception caused by a module Error
The second exception is captured in nunit and processed as a test failure. Sometimes we need to test whether the tested method throws the expected exception (for example, the specially passed error parameter), we can use the following method.
[Expectedexception (typeof (someexception)]
Or: [test, expectedexception (typeof (someexception)]
Note that the remaining code will be skipped once the expected exception is thrown.
5. Temporarily ignore some tests: Ignore
You can use the ignore feature when you write some test code but do not plan to execute it immediately.
[Test, ignore ("message")]
This test will be skipped and a yellow status bar will be displayed in the nunit GUI.
2.1.3. Use nunit assertions
Assertion is the most basic component of unit testing. nunitProgramLibraries provide different forms of assertions in the form of static assert methods, which are listed in Table 2.2 (nunit assertions.
Assertions in Table 2.2 nunit
1. areequals checks whether two values are equal
Assert. areequal (expected, actual [, string message])
Expected: Expected Value
Actual: actual value generated by the tested code
Message: optional parameter, indicating the Error Report Message
PS: in the comparison of floating point numbers, you also need to provide a parameter to indicate acceptable errors.
Assert. areequal (expected, actual, tolerance [, string message])
In this example, tolerance can be written as 0.01, indicating that it is accurate to the last two digits of the decimal point.
2. isnull check whether an object is null
Assert. isnull (object [, string message])
Assert. isnotnull (object [, string message])
Message: optional parameter, Error Report Message
3. aresame check whether the same object is referenced
Assert. aresame (expected, actual [, string message])
Message: optional parameter, Error Report Message
4. istrue checks whether the given binary condition is true.
Assert. istrue (bool condition [, string message])
Message: optional parameter, Error Report Message
5. Fail causes the test to fail immediately
Assert. Fail ([String message])
Message: optional parameter, Error Report Message
In nunit, you can also customize assertions for checking under specific conditions.
2.2. Testing skills: Test content
There are six specific parts worth testing, which can improve your testing level. These six aspects can be collectively referred to as right_bicep:
L right: whether the result is correct (right)
L B: whether boundary conditions are correct
L I: Can I check the Inverse association?
L c: Can I use other methods to cross-check results?
L e: Can error condition be reproduced?
L p: whether the performance meets the requirements
2.2.1. Whether the result is correct
For testing, the first and most obvious task is to check whether the expected result is correct-the verification result.
The result indicates that the code is consistent with your expectation.
2.2.2. Boundary Conditions
The boundary condition contains many content that will be described in the next section (. boundary condition.
2.2.3. Check reverse Association
For some methods, you can use reverse logical relationships to verify them. For example, to check whether a record is successfully inserted into the database, you can query this record for verification.
It is worth noting that when both the original method and its reverse testing are compiled, some bugs may be concealed by errors in both. When possible, different principles should be used for reverse testing.
2.2.4. Cross-check
Generally, more than one kindAlgorithm. You can use algorithms that are not used in the program for cross-check results-this algorithm may be slow or inflexible, but it will be very effective for cross-check.
2.2.5. Forcibly generate error conditions
You should be able to test how the code handles these problems by forcing errors in the real world, such as network disconnection and program crash. Simple errors such as invalid parameters are simple, but some special technologies are required to simulate complicated errors. In the following text, we will discuss how to use mock technology to solve the problem of force generation errors.
2.2.6. Performance Characteristics
The performance features here refer not to the performance of the program, but to the performance trend that "the problems become more and more complex as the scale increases. We should use a fast regression test with performance characteristics to avoid some modifications that make the program slow but cannot be located.