![JAR search and dependency download from the Maven repository](/logo.png)
com.google.testing.threadtester.AnnotatedTestRunner Maven / Gradle / Ivy
/*
* Copyright 2009 Weaver authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.testing.threadtester;
/**
* Runs a set of multithreaded tests defined by a series of annotations. To
* create a set of tests, define a class with a public no-arg constructor, and a
* set of publically annotated methods. A typical test setup would be:
*
*
* public class MyClassTest extends TestCase {
* public MyClassTest() {}
*
* private MyClass myClass;
*
* // This method is invoked as part of the regular unit test
* @Test
* public void runThreadedTests {
* new AnnotatedTestRunner().runTests(MyClassTest.class, MyClass.class);
* }
*
* @ThreadedBefore
* public void before() {
* myClass = new MyClass();
* }
*
* @ThreadedAfter
* public void after() {
* assertEquals("Hello World", myClass.getMessage());
* }
*
* @ThreadedMain(name="TestOne")
* public void testPrint() {
* myClass.printMessage("Hello");
* }
*
* @ThreadedSecondary(name="TestOne")
* public void testPrint2() {
* myClass.printMessage("World");
* }
* }
*
*
* The runner will run every test case defined in the test class. A test case
* consists of an initialisation method with the
* @ThreadedBefore
annotation, and a pair of execution
* methods, one with the {@link ThreadedMain} annotation, and one with the
* {@link ThreadedSecondary}. The execution annotations should have the same
* name. The test runner will run each pair of annotated methods in two separate
* threads, interleaving them to verify that the invoked calls are thread safe.
*
* Before invoking each method pair, the runner will invoke the method with the
* {@link ThreadedBefore} annotation. This method must create a new instance of
* the object being tested. Additional setup code common the all of the tests
* can also be added here. Note that only a single instance of the object under
* test can be created.
*
* After invoking each method pair, the {@link ThreadedAfter}
* method will be invoked. This can be used to verify results, and to free
* resources.
*
* A test case may also contain an optional third method tagged with the {@link
* ThreadedVerification} attribute. This will be invoked after the named test
* case has been run, and can be used to verify that the particular case has run
* successfully.
*
* The sequence for a test case named "test1" is thus:
*
* - @ThreadedBefore
*
- @ThreadedMain("test1")
*
- @ThreadedSecondary("test1")
*
- @ThreadedVerification("test1");
*
- @ThreadedAfter();
*
*
* The interleaving of the main and secondary methods is handled automatically
* by the test framework. It will analyse the @ThreadedMain
* method to find the first call to a method in the class-under-test. For each
* executable line in the target method it will then:
*
* - Invoke the
@ThreadedBefore
method
* - Invoke the
@ThreadedMain
method, and pause it at the line
* - Invoke the
@ThreadedSecondary
method
* - Allow the
@ThreadedMain
method to continue
* - Invoke the
@ThreadedAfter
method
*
*
* Finally, the entire test class may define one static method with the {@link
* ThreadedBeforeAll} annotation, and one static method with the {@link
* ThreadedAfterAll}. These methods are invoked before and after all of the test
* cases have been run.
*
* @see BaseThreadedTestRunner
* @see Instrumentation
*
* @author [email protected] (Alasdair Mackintosh)
*/
public class AnnotatedTestRunner extends BaseThreadedTestRunner {
@Override
protected String getWrapperName() {
return AnnotatedTestWrapper.class.getName();
}
}