.net Nunit continuous integration test configuration of the test article

Series catalog

Before we look at the beginning of a trap

Use the Person class as follows

 public class Person:IPerson
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public DateTime BirthDay { get; set; }
        /// <summary>
        /// 判断Name是否包含字母B
        /// </summary>
        /// <returns></returns>
        public bool WhetherNameContainsB()
        {
            if (this.Name == null) throw new ArgumentNullException("参数不能为null");
            if (this.Name.Contains("B")) return true;
            return false;
        }
    }

This class was also used, and there are three attributes a method, wherein the method for determining whether the Name field capital letters B, if included returns true, does not contain returns false, or null if thrown Name

Test class as follows

   [TestFixture]
    public class FirstUnitTest
    {
        private Person psn;
        public FirstUnitTest()
        {
         psn = new Person();
         }

        [Test]
        [Order(1)]
        public void SetPersonName()
        {
            psn.Name = "sto";
            Assert.IsNotEmpty(psn.Name);
        }
        [Test]
        [Order(2)]
        public void DemoTest()
        {
            Assert.Throws<ArgumentNullException>(() => psn.WhetherNameContainsB());
        }
       

    }

The first test to Name assignment, and then assert that the username is not empty, which obviously should be adopted

The second test will be used to throw an exception when calling the assertion WhetherNameContainsB, due here Name and no value, it will throw an exception, should be able to return to success here.

However, running the above code returns the second test is a failure! This is because Nunit in class when running the test will call all test methods, due to the operation of the order we explicitly specify (使用order注解)the method before the first before the second method when executed, because the first method is set to Name "sto", so this time the Name field will have the value of a global psn. so the second method and then call the method WhetherNameContainsB psn is to not throw (method the logic is that only the Name value there will not throw an exception).

If you run the order is not specified, the results of the second working is uncertain if it is performed prior to the first method, it will return success if later than the first method failed to return.

We mentioned earlier, the results of unit tests should be stable, but here it is uncertain, so we have to be redesigned.

In fact, of course, to solve this problem is very simple, as long as the move to global variables inside a method on the line, so that the state of each method will not be changed outside.

After transformation test class as follows

 [TestFixture]
    public class FirstUnitTest
    {
       
        public FirstUnitTest()
        {
        
         }

        [Test]
        [Order(1)]
        public void SetPersonName()
        {
            Person psn = new Person();
            psn.Name = "sto";
            Assert.IsNotEmpty(psn.Name);
        }
        [Test]
        [Order(2)]
        public void DemoTest()
        {
            Person psn = new Person();
            Assert.Throws<ArgumentNullException>(() => psn.WhetherNameContainsB());
        }
       

    }

We run, it can be passed.

However, such a design problem, first if multiple test methods to be used in this object, you need to copy a lot, if shared between multiple second method's code is very large, each method should be replicated in a lot of code we said earlier in the unit test code should be concise and clear, and copy the same code is not conducive to the maintenance. Here we introduce Nunit in the Setup

Setup注释

If the method of adding a comment setup, then the method will be subject to other methods is not performed in the unit test class, and 每个方法执行之前都会执行它, if in the previous method, the setup annotation object is initialized, the method of operating each of the runs annotated methods, variables are re-initialized every time, there will be no problems caused by the sharing of data. we use the test class after setup follows the transformation

    [TestFixture]
    public class FirstUnitTest
    {
        private Person psn;
        public FirstUnitTest()
        {
        
         }

        [SetUp]
        public void Setup()
        {
            psn = new Person();
        }
        [Test]
        [Order(1)]
        public void SetPersonName()
        {
          
            psn.Name = "sto";
            Assert.IsNotEmpty(psn.Name);
        }
        
        [Test]
        [Order(2)]
        public void DemoTest()
        {
           
            Assert.Throws<ArgumentNullException>(() => psn.WhetherNameContainsB());
        }
       

    }

In the process we identified as Setup's initialization Person, so that will be able to pass the test

Setup is annotated method name can be arbitrarily taken, as long as you can meet the naming conventions

Nunit does not limit a test class has multiple Setup methods, but strongly recommended.

OneTimeSetup comments

OneTimeSetup is run before every test method is run, except that it is not the same as the SetUp method runs before each test run, but the run before all the test methods run it once it applies to this scenario: For example, our program data access closed in the class, the class a variety of methods which are generally accessible database and some private variables like data access method in the connection string like only to read these fields rather than to modify it. the most it is important to all entities of such a class would be very resource-intensive method before each test run. like this type can be placed OneTimeSetup method, the run once when the class is created.

This method functions much like a constructor, it can do the work of the general constructor can do.

Teardown

Setup and Teardown usage of the same, but it is only run after run test methods, if our test method, there needs to release objects can be released in this method.

OneTimeTearDown

It is only run once, functionally equivalent to the destructor for the class freed resources used after testing all the methods are based on executing the method are completed after all of the run.

Previous section we saw how well a given method of how to run a specific method before each unit test. The following explains how to run and run after run before the assembly where the unit before the test run.

There might be doubts sense to do so, indeed, most of the time we may not need to run some method before or after the assembly operation, but under certain circumstances to do so would really bring a great help to test. For example, the following scenario

  • We want to look at statistics run time of all test methods, this time we can start before the assembly StopWatch and get run time after the completion of all methods of operation, and written to the log. Of course, this may seem a bit silly.
  • ConfigurationManager.AppSetting might extensive use of the Web project [xxx] to get the web project configuration, this brings challenges to the test

    Since the unit test runtime environment is not a lot of time in the output directory of the program, so web project to use the method AppSetting configured in the web environment operating normally, but get the value of the unit test environment is Null, this will lead to test a large number of business not covered.

    When the test is hard to pass by reference to change this value, because often get AppSetting in value in the program, instead of setting, it often is not included in the method's parameters. Will not pass by reference to modify it.

    If we assign to AppSetting in the Setup, such as ConfigurationManager.AppSettings [ "user"] = "sto"; so at run time we can get to this value, but AppSetting is global, the program may use many methods to it, we have to write a Setup method in each test method was to copy it is clearly very boring.

    At this time we can run a method to assign AppSetting In this method before the assembly operation, when this test method is used to run AppSetting where you can get to the value.

    To do this, we need to create a class and add SetUpFixture comment on the class. Then add OneTimeSetUp and OneTimeTeardown comment on the method. Nunit such scans into this category when the assembly is loaded, and then deal with it .

    We look at the sample code

    [SetUpFixture]
    public  class AssemblySetup
      {
          [OneTimeSetUp]
          public void RunBeforeEveryMethod()
          {
              ConfigurationManager.AppSettings["user"] = "sto";
              ConfigurationManager.AppSettings["age"] = "32";
          }
      }

    After we create the class RunBeforeEveryMethodwill run in the assembly before any code running

We have seen on the results
Avatar
we can see, just looking for a way in which to get the value of the test class, you can get to.

Earlier we explained how to run before and after the method, all methods before and after the test class to run and how in the assembly, let's talk about how to customize a way to run before / after running the test method.

Custom method has the advantage of the code if the setup for each test class in running basically the same, just a little slight difference, this will lead to code duplication. For example, we want to record some logs and after the run method before, so we the method can be implemented to run a custom test method before and after the run the custom methods, reducing code duplication.

To implement a custom method of operation, we want to inherit TestactionAttribute
sample code as follows

public class MyTestAction:TestActionAttribute
    {
        public override void BeforeTest(ITest test)
        {
            Console.WriteLine("★★★★★★★★★★" + test.FullName);
        }
       
    }

We simulated use Console.WriteLine.

Itest Nunit injected from the object at runtime.

Then we have to add on a run like this custom method of MyTestActionannotation can be.

Custom run method is very powerful and can also provide parameters, this will significantly reduce duplication of similar codes, improve maintainability, we have to future tests gradually began to feel.

Guess you like

Origin www.cnblogs.com/tylerzhou/p/11318911.html