Before stepping into the TDD cycle, I like to sketch out the tests that need to be implemented - i.e. write empty test methods with speaking names.
Unfortunately I have not found a way to "paint them yellow" - mark them as pending for JUnit. I can make them either fail or pass. Now I am letting them fail by throwing an Exception, but I'd rather use an equivalent of pending from rspec.
Is there such an option in JUnit or an "adjacent" library?
You can use #Ignore to ignore the test,
or this library to introduce the #PendingImplementation annotation:
https://github.com/ttsui/pending
I don't think there are other ways to achieve this..
You could use Assume or #Ignore, both are not quite what you are after but close. The 3rd party library pending also exists. I have not used it, but appears to do what you want.
Related
Why would one use JUnit's assumingThat() method instead of a plain old simple if clause? If one can use simple thing why would you complicate it with something else that does it the same way.
Is it just a expressionality thing, or what's the advantage, I don't see other benefits.
Junit's assume is not a new feature in version 5, it has been there since v4.4 and it has other applications.
You could skip testing with if, but with assume you can tag failure lifecycle method to it, using a Listener.
Example Situation (Most Common) - You could have a listener, which creates reports of the test. And there could be a code to add the failed tests, passed tests and assume failed tests to the report. If you want to achieve this without using listener or testAssumptionFailure method, then you would have to repeatedly call it everywhere.
Instead adding a listener makes it modular and maintainable.
You have many varities of assume methods which you could use to stop repeatedly write if, else and messages.
All JUnit assert methods have an optional first parameter being the message printed when the assertion fails.
How do I ensure the parameter is always passed, and developers in my project never lazily skip describing what the assertion is doing?
Is there an inspection tool that can check for that?
Is there anything I can do programmatically?
My project is maven-friendly.
As code inspection seems to be your aim, I would recommend a tool called PMD. If there is not already a rule for this, I would think it is fairly trivial to create one. Furthermore, this will help you in detecting other code mess which your developers may be creating.
Here is a link:
http://pmd.sourceforge.net/
In our team, we do code reviews of pull requests. If asserts are not following the standard, you could flag it in the review. Only pull requests that have sufficient approvals are allowed to be merged.
That said, I would probably not enforce this rule on my team. Instead I'd tell them to write shorter tests where the method name will clearly state the intent, like:
#Test(expected = IllegalArgumentException.class);
shouldThrowExceptionWhenInputIsNegative() {}
#Test
shouldFilterOutNulls() {}
#Test
shouldCreateAdditionalRecordWhenBankBalanceIsOver10000() {}
etc...
My company wants to move off of JUnit 3 and start using only JUnit 4. The other intern and I have been given the task of converting the older JUnit 3 tests to use JUnit 4 conventions. However, I'm having a problem converting the testfile I'm working on right now.
From what I can tell, there is a generateTest method that returns a SSlTest (SSlTest is a subclass of TestCase). The returned SslTest overrides runTest. runTest contains a try-catch block that starts two threads, clientThread and serverThread (these are both subclasses of Thread that are defined within the testfile). It looks like the actual testing is being done inside the threads, since the rest of runTest is used for catching exceptions from the two threads.
generateTest is called by another method, generateSuite (returns a TestSuite). generateSuite contains an outer for-loop that adds suites to a main suite. The inner for-loop uses generateTest to add tests to each suite within the main suite. The main suite is what is returned by the method.
Finally, inside the suite() method that is called in the main method of the test file, a while-loop is setup to generate suites using generateSuite and add them to a bigger suite.
The only guides I've found on migrating to JUnit 4 are for much simpler test cases. I'm very lost right now and no one else at my company knows enough JUnit 4 to help me, so any tips would be much appreciated!
The very first thing I would do is try to convince whomever gave me the task that it is unnecessary. I know that is hard as an intern, but it is worth making sure that person understands this isn't necessary.
Facts for convincing:
The JUnit 4 jar contains both the junit.framework and org.junit package structures so it is backward compatible.
JUnit has broad adoption. They owners of the JUnit project are well aware of this and aren't going to ask people to rewrite all the tests. In other words, they aren't going to just drop compatibility.
Actually try it. Seriously. Try running your existing test code as is with the JUnit 4 jar. You'll see if you get any compiler errors. If you do, those are the areas to focus. If you don't, you have great evidence to show to the person who gave you the task.
This doesn't mean you won't have to change anything. It means you won't have to change the majority of your code. If you have custom runners, you'll want to use the JUnit 4 style. You also might need classpath suite to collect the tests.
There is also value in converting a few of the tests to the JUnit 4 so developers on the team have some examples to use. But converting them all isn't a good use of time.
On not being able to post code
Getting help on the internet is extremely difficult without code. I can understand your employer not wanting you to post code. (But then they probably don't want you posting class and method names either - which you did.) Luckily, there is an alternative. Create a SSCCE instead. (Read the link - it will help you a lot as you progress in your jobs.) In addition for the smaller example being easier to read, it will allow you to change the class/method/etc names and then your employer won't have their code online.
I would like to find unit tests (written with JUnit) which never fail. I.e. tests which have something like
try {
// call some methods, but no assertions
} catch(Throwable e) {
// do nothing
}
Those tests are basically useless, because they will never find a problem in the code. So is there a way to make each (valid) unit test fail? For instance each call to any assert method would throw an exception? Then tests which still remain green are useless.
Well, one approach is to use something like Jester which implements mutation testing. It doesn't do things quite the way you've suggested, but it tries to find tests which will still pass however much you change the production code, but randomly mutating it and rerunning the tests.
If you are trying to make every call to every Assert method fail, then I'm not certain how to help you. #JonSkeet's suggestion of Jester may be close to what you want.
However, if you're trying to find an Assert method that always fails, Assert.fail is what you want. It throws an AssertionError on invokation.
I'm assuming that you want to track code that swallows assertions, and/or does not make any assertions. The simplest way to do this will be to build your own JUnit JAR, replacing the original Assert class with your own.
This won't help you find cases where the assertions are bogus, and if you're in an environment where developers don't bother to assert, you're likely to have bogus assertions as well. It also doesn't help you find tests that are marked with #Ignore, but grep will do that for you.
Add this as your default test implementation:
Assert.assertTrue(false);
Every test that starts this way will fail until you replace that line with something suitable.
I'm not sure about what you want but I understand that the Units are already written, so the only way I can imagine is to override the asserts methods, but even with this you will have to change a little bit the unit code.
Run CheckStyle against your JUnit sources with the following configuration:
<module name="IllegalCatch">
<property name="illegalClassNames" value="java.lang.Throwable, java.lang.Error, java.lang.AssertionError"/>
</module>
As far as I know to skip a test case the simplest thing to do is to remove the #Test annotation, but to do it over a large number of test cases is cumbersome. I was wondering if there is any annotation available in JUnit to turn off few test cases conditionally.
Hard to know if it is the #Ignore annotation that you are looking for, or if you actually want to turn off certain JUnit tests conditionally. Turning off testcases conditionally is done using Assume.
You can read about assumptions in the release notes for junit 4.5
There's also a rather good thread here on stack over flow:
Conditionally ignoring tests in JUnit 4
As other people put here #Ignore ignores a test.
If you want something conditional that look at the junit assumptions.
http://junit.sourceforge.net/javadoc/org/junit/Assume.html
This works by looking at a condition and only proceeding to run the test if that condition is satisfied. If the condition is false the test is effectively "ignored".
If you put this in a helper class and have it called from a number of your tests you can effectively use it in the way you want. Hope that helps.
You can use the #Ignore annotation which you can add to a single test or test class to deactivate it.
If you need something conditional, you will have to create a custom test runner that you can register using
#RunWith(YourCustomTestRunner.class)
You could use that to define a custom annotation which uses expression language or references a system property to check whether a test should be run. But such a beast doesn't exist out of the box.
If you use JUnit 4.x, just use #Ignore. See here