. NET programmers must be aware of the context Environment check during execution of integration test cases in the Dev environment)
From the beginning of this article, I will share a series of core technical points of. NET project development that I think are necessary in actual work. Although these columns are used. NET/C #, but it is also applicable to other similar OO technology platforms. These technical points may not be fully described, but it is a summary of experience, it is the Awakening after many pitfalls, so it takes several minutes to remember it. In real project development, you will know how helpful it is. Now, let's get started with the theme. During service development, we conduct a basic module test locally for debugging convenience. You can also think of it as an integration test, but your test cases won't cover more than 80%, instead, we think that appropriate use cases can be written to test it, rather than at ease during development. Integration test cases usually have multiple execution contexts. For our developers, our execution contexts are usually local, and the testers are in the test environment. Tests by developers cannot be connected to other environments (of course, depending on the specific situation, some use cases are dangerous and cannot be connected randomly. This article will explain how to solve this problem ), all resources and services to be accessed in the integrated test cases run by developers are in the development environment. This still exists, but for debugging convenience, we still need to be able to connect to other environments for debugging as necessary, in order to simulate the problematic environment and real data, we need to have such a mechanism. When necessary, I can open a setting so that it can switch the environment context of the integrated test run, to put it bluntly, it is the connection address of the environment and data source that you want to connect. In this article, we will use a simple example to learn how to simply handle this situation. This is actually based on the effect of testing for continuous refactoring. Copy the Code 1 using System; 2 using Microsoft. visual Studio. testTools. unitTesting; 3 4 namespace OrderManager. test 5 {6 using ProductService. contract; 7 8 // <summary> 9 // Product service integration tests.10 // </summary> 11 [TestClass] 12 public class ProductServiceIntegrationTest13 {14 // <summary> 15 /// service address.16 /// </summary> 17 public const string ServiceAddress =" http://dev.service.ProductService/ "; 18 19 /// <summary> 20 // Product service get product by pid test.21 /// </summary> 22 [TestMethod] 23 public void ProductService_GetProductByPid_Test () 24 {25 var serviceInstance = ProductServiceClient. createClient (ServiceAddress); 26 var testResult = serviceInstance. getProductByPid (0393844); 27 28 Assert. areNotEqual (testResult, null); 29 Assert. areEqual (testResult. pid, 0393844); 30} 31} 32} copy the Code. This is The actual integration test case code has a service address shared by the current test class, which is in the DEV environment. Of course, you can also define the service address of several other environments, the premise is that the environment allows you to connect. Let's take a look at the test case. It is a query method test case for ProductServiceClient. the GetProductByPid service method is used for testing. Because the query-oriented operations are implemented on the same screen, no matter how many times we query the Product of this ID, it will not affect the data, however, if we test an update or delete operation, it will cause problems. In the DEV environment, there is no problem in testing update and delete use cases. However, if your machine is able to connect to a remote production or PRD test, it may bring a certain risk, especially when you are busy, it is hard to remember whether the host configuration of your current machine is still connected to a remote production machine, or you don't need to configure the host to connect to an environment you shouldn't connect. This is the current problem. So how can we solve this problem? by performing a simple reconstruction of the test code, we can avoid the danger of running the test case in the environment that should not be connected. In fact, many times, Refactoring can really help us find the exit, as the saying goes: "The exit is turning around". Only continuous reconstruction can ensure the quality of the project gradually, this effect is rare. Extract the abstract base class and define the environment to be accessed. Copy code 1 namespace OrderManager. test 2 {3 public abstract class ProductServiceIntegrationBase 4 {5 // <summary> 6 // service address. 7 /// </summary> 8 protected const string ServiceAddressForDev =" http://dev.service.ProductService/ "; 9 10 /// <summary> 11 // service address.12 // </summary> 13 protected const string ServiceAddressForPrd =" http://Prd.service.ProductService/ "; 14 15 /// <summary> 16 // service address.17 /// </summary> 18 protected const string ServiceAddressTest =" http://Test.service.ProductService/ "; 19} 20} copy the code to eliminate repeated code for the specific test class and add a unified constructor. Copy the Code 1 using System; 2 using Microsoft. visual Studio. testTools. unitTesting; 3 4 namespace OrderManager. test 5 {6 using ProductService. contract; 7 8 // <summary> 9 // Product service integration tests.10 /// </summary> 11 [TestClass] 12 public class ProductServiceIntegrationTest: productServiceIntegrationBase13 {14 // <summary> 15 // product service client.16 /// </summary> 17 private ProductServi CeClient serviceInstance; 18 19 /// <summary> 20 // Initialization test instance.21 /// </summary> 22 [TestInitialize] 23 public void InitTestInstance () 24 {25 serviceInstance = ProductServiceClient. createClient (ServiceAddressForDev/* for dev */); 26} 27 28 /// <summary> 29 // Product service get product by pid test.30 /// </summary> 31 [TestMethod] 32 public void ProductService_GetProductByPid_Test () 33 {34 var testResult = serviceInstance. get productbypid (0393844); 35 36 Assert. areNotEqual (testResult, null); 37 Assert. areEqual (testResult. pid, 0393844 ); 38} 39 40 // <summary> 41 // Product service delete search index test.42 // </summary> 43 [TestMethod] 44 public void ProductService_DeleteProductSearchIndex_Test () 45 {46 var testResult = serviceInstance. deleteProductSearchIndex (); 47 48 Assert. isTr Ue (testResult); 49} 50} 51} After copying the code to eliminate repeated code, we need to add a test case to check whether the code can be connected to an environment. I added a DeleteProductSearchIndex test case to test the deletion of search indexes, this test case can only be run in the local DEV environment (You may think that this Delete interface should not be put in this service. Here is just an example, so you don't need to worry about it ). In order to have a check mechanism to remind developers of the current connection address, we need to use the test context. After reconstruction, let's take a look at the current test code structure. Copy the Code 1 using System; 2 using Microsoft. visual Studio. testTools. unitTesting; 3 4 namespace OrderManager. test 5 {6 using ProductService. contract; 7 8 // <summary> 9 // Product service integration tests.10 /// </summary> 11 [TestClass] 12 public class ProductServiceIntegrationTest: productServiceIntegrationBase13 {14 // <summary> 15 // product service client.16 /// </summary> 17 private ProductServi CeClient serviceInstance; 18 19 /// <summary> 20 // Initialization test instance.21 /// </summary> 22 [TestInitialize] 23 public void InitTestInstance () 24 {25 serviceInstance = ProductServiceClient. createClient (ServiceAddressForPrd/* for dev */); 26 27 this. checkCurrentTestCaseIsRun (this. serviceInstance); // check current test case. 28} 29 30 /// <summary> 31 // Product service get product by pid test. 32 // </summary> 33 [TestMethod] 34 public void ProductService_GetProductByPid_Test () 35 {36 var testResult = serviceInstance. getProductByPid (0393844); 37 38 Assert. areNotEqual (testResult, null); 39 Assert. areEqual (testResult. pid, 0393844); 40} 41 42 // <summary> 43 // Product service delete search index test.44 // </summary> 45 [TestMethod] 46 public void ProductService_DeleteProductSearchIndex_Test () 47 {48 var testResult = serviceInstance. deleteProductSearchIndex (); 49 50 Assert. isTrue (testResult); 51} 52} 53} copy the code. We have added an important test instance runtime method InitTestInstance, which will be executed before each test case is instantiated, there is an environment inside the method to check the current test case running this. checkCurrentTestCaseIsRun (this. serviceInstance); // check current test case ., go to the base class. Copy the Code 1 using System; 2 using Microsoft. visual Studio. testTools. unitTesting; 3 4 namespace OrderManager. test 5 {6 public abstract class ProductServiceIntegrationBase 7 {8 /// <summary> 9 /// service address.10 /// </summary> 11 protected const string ServiceAddressForDev =" http://dev.service.ProductService/ "; 12 13 /// <summary> 14 // get service address.15 /// </summary> 16 protected const string ServiceAddressForPrd =" http://Prd.service.ProductService/ "; 17 18 /// <summary> 19 // service address.20 /// </summary> 21 protected const string ServiceAddressTest =" http://Test.service.ProductService/ "; 22 23 // <summary> 24 // Test context. 25 /// </summary> 26 public TestContext {get; set ;} 27 28 /// <summary> 29 // is check is run for current test case.30 /// </summary> 31 protected void CheckCurrentTestCaseIsRun (ProductService. contract. productServiceClient testObject) 32 {33 if (testObject. serviceAddress. equals (ServiceAddressForPrd) // Prd environment, check 34 {35 if (this. testContext. tes TName. Equals ("ProductService_DeleteProductSearchIndex_Test") 36 Assert. IsTrue (false, "the current test case connection environment is PRD. Please stop running the current test case. "); 37} 38 else if (testObject. serviceAddress. equals (ServiceAddressTest) // Test environment, check the conventions for several use cases 39 {40 if (this. testContext. testName. equals ("ProductService_DeleteProductSearchIndex_Test") 41 Assert. isTrue (false, "the current TEST case connection environment is TEST. To avoid damaging the TEST environment, stop the use case. "); 42} 43} 44} 45}