Any annotation to mark a class as a testclass? - java

I am new to Junit4, I am wondering if there is some annotations to mark a class as a test class just like using
#Test to mark a method as a test method.

You can use #Category annotation at class level, like:
#Category({PerformanceTests.class, RegressionTests.class})
public class ClassB {
#Test
public void test_b_1() {
assertThat(1 == 1, is(true));
}
}
I quoted this example from https://www.mkyong.com/unittest/junit-categories-test/
Also if you run Spring tests, Mockito test with JUnit, then you have to use #RunWith annotation at class level.
For example in Spring boot test I use this:
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
public class ControllerTest {
In Mockito (without spring test) test I used:
#RunWith(MockitoJUnitRunner.class)
public class ServiceTest {

Annotation #TestOnly, but it does come with a warning, as seen below.
import org.jetbrains.annotations.TestOnly;
WARNING
/**
* A member or type annotated with TestOnly claims that it should be used from testing code only.
* <p>
* Apart from documentation purposes this annotation is intended to be used by static analysis tools
* to validate against element contract violations.
* <p>
* This annotation means that the annotated element exposes internal data and breaks encapsulation
* of the containing class; the annotation won't prevent its use from production code, developers
* won't even see warnings if their IDE doesn't support the annotation. It's better to provide
* proper API which can be used in production as well as in tests.
*/
WORKAROUND
If there are bodies of code or classes that I use specifically for testing and need to remove them at release I add a custom TODO using Android Studio (Not sure if other IDEs have the same functionality), follow the screenshot below and in the TODO tab at the bottom, you will see a filter for each custom TODO on the left. This is by no means the best way to do it, but I find it the fastest manual way to remove code on release.
P.S I know the patterns are all sorts of messed up in this screenshot.

Related

Creating a configurable JUnit library to test same features across several microservices

A set of tests should be run on every microservice. Current solution is to have an abstract class and extend in every service, providing the necessary properties in abstract getters.
public abstract class AbstractTest {
#LocalServerPort
protected int serverPort;
protected abstract String getPath();
#Test
void someTest() {}
#Test
void conditionalTest() {}
}
#SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
classes = {...})
#ActiveProfiles(...) // etc
public class MyTest extends AbstractTest {
// ... implement getPath()
// tests from parent will be executed
}
The goal:
Ditch inheritance and have the AbstractTest's logic get executed automatically with conditional #Test execution based on beans/properties etc.
The possible solution:
A concrete class with all the tests or some sort of Configuration/TestFactory to create the necessary tests. It should take into account available properties and beans to determine which tests to run.
The problem:
How can those tests (created in runtime) be discovered and registered for execution?
How to inject all the properties that are part of the current context of the #SpringBootTest?
Failed attempts:
TestInstanceFactory extension doesn't seem to be the solution as it requires an instance of the class which it annotates.
Using the Launcher API seems overkill, and also doesn't seem to work, since the library class won't be created with the Spring context configs.
using cglib and a base class Spring Contract-style is not a desirable solution
Ideally I don't want the client of this lib to implement/create anything, so abstract String getPath(); would be a test.lib.path property, and if it's present, a test from the library which uses it will run.
Any thoughts on this would be great, because right now this just seems impossible to me.
What is the reason to have the inheritance for tests?
In case you need to share some common logic within the tests you may try JUnit features (custom rules/extensions), for example
For junit < 5.x.x #Rule functionality https://junit.org/junit4/javadoc/4.12/org/junit/rules/TemporaryFolder.html https://stackoverflow.com/a/34608174/6916890
For junit >= 5.x.x (jupiter) there is an extension API
https://junit.org/junit5/docs/current/user-guide/#writing-tests-built-in-extensions-TempDirectory

Is it possible to have a global setup method in Spock test?

I am a developer on a Grails/Groovy application which uses Spock as its framework for unit testing. The project has around 1000 unit tests, and I would essentially like to perform a specific mock / operation before running all tests. Preferably it should only be executed once, alternatively before each test - or before some large subset of all the tests. I imagine that it out to be possible to have a “global” setup method which all tests can extend. Is this possible?
Preferably it should only be executed once, alternatively before each
test - or before some large subset of all the tests. I imagine that it
out to be possible to have a “global” setup method which all tests can
extend. Is this possible?
Yes, it is possible. The specifics of how best to do it will depend on specifically what you want to accomplish but global extensions are likely candidates. See the "Writing Custom Extensions" section of http://spockframework.org/spock/docs/1.3/extensions.html for a lot of detail. There is a lot of flexibility there. We had great success writing custom extensions for Micronaut.
I hope that helps.
We ended up doing the following. First we defined a class implementing IAnnotationDrivenExtension interface:
class MockConfigMapExtension implements IAnnotationDrivenExtension<MockConfigMap> {
#Override
void visitSpecAnnotation(MockConfigMap annotation, SpecInfo spec) {
// WRITE THE RELEVANT STARTUP CODE HERE
}
#Override
void visitFeatureAnnotation(MockConfigMap annotation, FeatureInfo feature) {
}
#Override
void visitFixtureAnnotation(MockConfigMap annotation, MethodInfo fixtureMethod) {
}
#Override
void visitFieldAnnotation(MockConfigMap annotation, FieldInfo field) {
}
#Override
void visitSpec(SpecInfo spec) {
}
}
where we defined this trivial annotation:
#Retention(RetentionPolicy.RUNTIME)
#Target([ElementType.TYPE])
#ExtensionAnnotation(MockConfigMapExtension.class)
#interface MockConfigMap {
}
Now, whenever we annotate a Spec class with the MockConfigMap annotation, the visitSpecAnnotation method is invoked, and we get the desired behaviour.

Don't start nested test cases when outer test case fails with JUnit 5

I have the following test class:
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class HierarchicalTest {
#Test
void checkOuter() {
assertTrue(false);
}
#Nested
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
class PrepBTest {
#Test
void checkInnerA() {}
#Test
void checkInnerB() {}
}
}
I want to have the behavior that checkInnerA() and checkInnerB() won't be executed when checkOuter() fails.
On the other side checkInnerB() should be executed when checkInnerA() fails because it is on the same level.
Is there a simple soulution (e.g. with JUnit 5 extension) to achieve this behavior?
In my opinion that's often the behavior which is wished.
UPDATE:
As of JUnit Jupiter 5.4, you can develop an extension that implements the TestWatcher and ExecutionCondition APIs to achieve this behavior.
In the testFailed() method from the TestWatcher API you need to track test classes that have failures, and you need to store this information in the root ExtensionContext.Store.
In the evaluateExecutionCondition() method from the ExecutionCondition API you need to determine if the current class is a #Nested test class (i.e., an inner class) and check if the enclosing test class had failures. If that holds true, you need to disable the current #Nested test class and otherwise enable it.
Those are the general guidelines. For a working example, please see the SkipOnFailuresInEnclosingClassExtension I just posted to my junit5-demo repository on GitHub. That example goes one step further by only skipping #Nested test classes if they are also annotated with #SkipOnFailuresInEnclosingClass. The OuterTests class shows the annotation and extension in action.
No, as of JUnit Jupiter 5.3, there is currently no way to achieve that with out-of-the-box solutions.
You could potentially write a custom extension that tracks the success of tests in an enclosing test class -- for example, by implementing TestExecutionExceptionHandler. That would need to be stored in the ExtensionContext.Store. The extension would then need to implement ExecutionCondition to programmatically disable nested test classes.
It's unfortunately not very straightforward to track the "success" of previously executed tests currently, but that should improve with the introduction of the new TestWatcher extension API that is currently slated for inclusion in the upcoming JUnit Jupiter 5.4: https://github.com/junit-team/junit5/issues/542

How to get a collection of tests in a JUnit 4 test suite

In JUnit 3, I could get all of the tests within a test suite with the following code:
TestSuite allTestsSuite = (TestSuite) AllTests.suite()
Enumeration enumeration = allTestsSuite.tests();
ArrayList listOfTests = Collection.list(enumeration);
However, I can't find an equivalent way of doing this in JUnit 4. Classes no longer have a .suite() method; they simply use the #Suite annotation. This wouldn't be a problem except that the Suite class no longer has a tests() method. There is a children() method, but that returns a list of Runners, which seem to be something different than why I'm looking for.
So how can I get the tests within a test suite in JUnit 4, like I could with JUnit 3?
The simplest way to perform any kind of filering is to create your own JUnit Categories.
See this Junit Category tutorial for more details but basically, you create your own categories named whatever you want
public interface GuiTest{ }
public interface DbTest { }
And now you can annotate either entire test classes or individual tests with that category:
#Category(GuiTest.class)
public void myJPanelTest{
#Test
public void testFoo(){
...
}
//look we can have other categories too
#Test
#Category(DbTest.class)
public void accidentalDbTest(){
}
}
Then in your test suite, you can specify to include or exclude tests that match the given category
#RunWith(Categories.class)
#IncludeCategory(GuiTest.class)
#ExcludeCategory(DbTest.class) //not sure if we need both but can't hurt
#SuiteClasses( {
...
})
public class GuiTestsOnlySuite{}
Using Categories is much better than having to come up with manually filtering tests based on ad-hoc naming conventions because it that is hard to remember to do (and to make sure everyone in your group adheres to the naming conventions) and since the categories are classes, you can use your IDE to search/refactor/ compile time check your category names.
The only downside I've seen is at least in my IDE, the tests take a little longer to run because there is extra reflection work to do to make sure the test matches your category filter criteria before it runs.
After a bit of experimentation, I discovered the following solution:
SuiteClasses suiteClassesAnnotation = AllTests.class.getAnnotation(SuiteClasses.class);
if (suiteClassesAnnotation == null)
throw new NullPointerException("This class isn't annotated with #SuiteClasses");
Class<?>[] classesInSuite = suiteClassesAnnotation.value();
Basically, it gets the classes the same way that JUnit itself gets them: by looking into the annotation and determining which values are included within it.
The category solution provided by dkatzel is also a good option if you're ultimately wanting to filter these classes, but if you need a list of classes in a suite for some other purpose such as code analysis, this is the simplest and most direct way to do it.

Independent JUnit Tests with Springs #Autowired

As a beginner in Test Driven Development I just encountered a problem. My test class begins as follows:
#RunWith(SpringJUnit4ClassRunner.class)
#Transactional
#DirtiesContext
#ContextConfiguration(locations = {"/web-test.xml"})
public class XXTest {
#Autowired
XX xx;
#Autowired
HibernateTemplate template;
#Test
public void testSetGetXXValue() throws Exception {
final Map<String, YY> profilMap = new HashMap<String, YY>(2);
profilMap.put("1", new YY());
profilMap.put("2", new YY());
simpleCockpit.setValues(profilMap);
assertEquals(profilMap, simpleCockpit.getValues());
}
As you can see, the first test method alters the autowired XX-class. That affects all following test methods, which relies on XX having the autowired-values.
How can I test getter and setter from XX AND make sure XX has the autowired values for the rest of the test methods?
Thoughts:
Reset the right values at the end of test method. Bad because if the getter / setter are not working, this will also not work.
Place the first test method at the end of the test class. Bad because that makes the tests dependent on their execution order.
Do not test the getter / setter of XX. Bad because getter / setter have to be tested like every method.
Thanks for you answers! I`m pretty sure this has an easy solution ... :)
EDIT: Regarding the questions whether unit testing getters/setters or not, I decided to do so mainly because of the reasons statet at http://www.sundog.net/sunblog/posts/should-we-test-getters-and-setters/ .
If you modify an spring managed bean, then you could use the #DirtiesContext Annotation. This Annotation can be put on Test Classes as well as on Test Methods!
From #DirtiesContext Java Doc:
Test annotation which indicates that the {#link
org.springframework.context.ApplicationContext ApplicationContext}
associated with a test is dirty and should be closed:
after the current test, when declared at the method level
after each test method in the current test class, when declared at the class
level with class mode set to {#link ClassMode#AFTER_EACH_TEST_METHOD
AFTER_EACH_TEST_METHOD}
after the current test class, when declared
at the class level with class mode set to {#link ClassMode#AFTER_CLASS
AFTER_CLASS}
And even in Test Driven Development (to my understanding): write explicite tests only for stuff that has a minimum complexity. So I never write explicite tests for getter and setter. I normally have a test that checks some functionality, and when this functionality needs the getter and setter so I write this getter and setter (at this point in time) and that they works will be checked by the functionality I started with implicit.
Especially in your case: why do you use the Spring Bean, why not using "normal" Objects created with new. I use the "normal" classes as long as it is usefull for the tests, mostly for simple tests. I use Spring Beans for "bigger" tests as well.

Categories