Write a test framework | Java development practice

Posted by Alex C on Sun, 30 Jan 2022 03:00:08 +0100

1, Foreword

Requirements: a testing framework is needed to test an IM} system and adapt to the current business logic.

Testing uses Jmeter. Jmeter can also test websocket. Why develop a testing framework yourself?

The most important point: TCP # protocol is user-defined. It cannot be well integrated with # Jmeter # and other frameworks. PS: of course, Jmeter is not deep enough.

Then, for an IM # system, the corresponding test framework shall meet the following requirements:

  1. Coherence and context: when the connection is maintained, certain business logic processing is performed, such as sending messages, adding groups, adding friends, etc
  2. Easy access: the development of docking code is simple
  3. Generate many different reports
  4. Extensible

Well, try it.

2, v1 version

In the initial stage, this kind of automatic test needs to meet the following requirements:

  1. Automatic execution: all test cases can be executed after startup. Failure of one test case cannot affect other test cases
  2. You can output customized reports: print and generate files on the console
  3. Simple enough: easy to integrate business, can be developed, and run fast

Thinking process

Thinking process:

  1. The test case should be an object
  2. Test cases should be isolated from each other
  3. How to run multiple test cases?
  4. How to save exceptions that occur when a test case runs?

(1) The test case should be an object

Run: is a capability, so it can be abstracted as interface} interface:

public interface Test {

    void run();
}

The test case should be an object, and each case comes from a template:

With attribute: case name = name

public abstract class TestCase implements Test {
    protected String name;
    
    public TestCase() {
    }

    public TestCase(String name) {
        this.name = name;
    }
    
    @Override
    public void run() {
     
    }
}

(2) Test cases should be isolated from each other

Test cases should be isolated from each other:

  1. The operation of one use case should not affect another use case
  2. Some preparation is required before running test cases
  3. Some cleanup is required after running the test cases

Export template method mode in design mode. The code is as follows:

public abstract class TestCase implements Test {
    protected String name;
    
    public TestCase() {
    }

    public TestCase(String name) {
        this.name = name;
    }
    
    @Override
    public void run() {
        setUp();
        
        try{
            runTest();
        } finally {
            tearDown();
        }
    }
    
    protected void setUp() throws Exception {}
    protected void runTest() throws Exception {}
    protected void tearDown() throws Exception {}
}

(3) How to run multiple test cases?

So far, this framework can only run one custom TestCase at a time.

Can you:

  1. Can you run multiple "transparently"?
  2. The caller doesn't care whether the call is one or more?

This uses the # combination pattern in the design pattern, corresponding to the class diagram, as shown in the figure:

The code is as follows:

public class TestSuite extends TestCase {

    private final List<Test> fTests = new ArrayList<>();
    
    @Override
    public void run() {
        for (Test test : this.fTests) {
            test.run();
        }
    }
    
    public void addTest(Test test) {
        this.fTsets.add(test);
    }
}

Actual operation, for example:

TestSuite testSuite = new TestSuite();
testSuite.addTest(new CalculatorTest('test1'));
testSuite.addTest(new CalculatorTest('test2'));

TestSuite ts = new TestSuite();
ts.addTest(new CalculatorTest('test3'));
testSuite.addTest(ts);

testSuite.run();

(4) How to save exceptions that occur when a test case runs?

The test fails, and the code throws an exception: Error.

At this time, the class TestResult is introduced to collect results.

Important test results are as follows:

public class TestResult {
    private List<TestFailure> errors;

    ... ...
    // Important:
    void run(final TestCase test) {
        startTest(test);
        try {
            test.doRun();
        } catch (Throwable e) {
            addError(test, e);
        }
        endTest(test);
    }

    private void startTest(Test test) {
        int count = test.countTestCases();
        testCount += count;
    }

    private void endTest(Test test) {}
}

Other corresponding modification codes are as follows:

// Test.java is as follows:
public interface Test {
    void run(TestResult tr);
    int countTestCases();
}


// TestCase.java is as follows:
public abstract class TestCase implements Test {

    ... ...
    // Important:
    @Override
    public void run(TestResult testResult) {
        testResult.run(this);
    }

    ... ...
}

So to summarize the current calling process:

Summary

What design patterns have been used so far:

Each thinking step corresponds to a design pattern.

  1. Command mode: express a Test case, i.e. Test
  2. Template mode: complete data preparation and cleaning, setUp() and tearDown()
  3. Combination mode: mask the difference between one and more, list < test >
  4. Collect parameter mode: use parameters to collect information and isolate test cases and test results

 

Careful students have found that this is not the castrated version of Junit!!!

yes. It imitated Junit 3 and Junit 4 and began to be revised again.

The following figure shows the framework of "junit3":

But Junit has an important idea: agreement is better than configuration.

That is, Junit , will load the methods starting with , test , as test cases. Now it looks very simple, but the idea is very important!!!

If I think the article is helpful to you, please praise, comment and collect. Your support is my biggest motivation!!!

Finally, Xiaobian sorted out some learning materials during the learning process, which can be shared with Java engineers and friends to exchange and learn from each other, If necessary, you can join my learning exchange group 716055499 to obtain Java architecture learning materials for free (including architecture materials of multiple knowledge points such as high availability, high concurrency, high performance and distribution, Jvm performance tuning, Spring source code, MyBatis, Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx, etc.)

Author: dingyu002

Source: dinyu002

The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.

 

Topics: Java Programming Spring Design Pattern Distribution