Using gradle, exclude junit test except when doing distribution task - java

I have some slow jUnit tests that I typically skip during a build using a SlowTests category, e.g.
myjava.java
package com.mycompany.package;
public interface SlowTests { }
public class MyTests {
#Category(SlowTests.class)
#Test
public final void testSomethingTakingALongTime() {
// Some test that takes a while (say over 10 seconds) to run.
}
}
build.gradle
// Gradle stuff...
test {
useJUnit {
excludeCategories 'com.mycompany.package.SlowTests'
}
}
// More gradle stuff...
However, I would like to include these slow running tests before doing a the publish task.
Any ideas on how I might be able to achieve this?
Would just adding a second task that publish depends on be the easiest solution?

Related

Why Unit Tests Assertion fail on Gradle 5.1, but passes on 1.12, both use same Java version 1.8?

I have a multi-module project which is using
Java 1.8
JUnit 4.12
Gradle
When compiling a single module, its unit tests are failing on asserting null with Gradle 5.1, but same tests pass on Gradle 1.12 and module compiles successfully. Not changing anything except what is deprecated in 5.1. I can't understand why same framework fails on a recent Gradle version.
One test fails on JUunit Assert.assertNotNull(), which is checking for a string is null or not.
A second test fails on JUnit Assert.assertTrue().
build.gradle is same in both except configuration name changes and I have confirmed all dependencies are downloaded and compiling.
Can't share build script, but if you don't understand something I'll try to make a pseudo script.
I thought assertion errors were more related to language version than tools?
public class Test {
private String property;
#Before
public void setUp() {
property = Singleton.getInstance().getProperty();
}
// test failure 1
#Test
public void shouldAbleToGetProperty() {
assertNotNull(property);
}
// test failure 2
#Test
public void shouldReturnTrueIfPropertyIsTrue() {
Assert.assertTrue(Singleton.getInstance().isTrue());
}
}
Singleton class is a normal singleton which reads property files in resources folder.
NOT ACTUAL CODE
class Singleton {
private Map<String, Properties> properties;
public static Singleton getInstance() {
// return singleton as its meant to be ...
// read property file from project and hold it in map.
}
}

Get top-most executing TestSuite in JUnit

I need to know the suite class that included the currently running JUnit test. For example, if you have
#SuiteClasses({SubSuite.class})
class ParentSuite { }
#SuiteClasses({TestCase.class})
class SubSuite { }
class TestCase {
#Test
public void testMethod() { }
}
and execute ParentSuite with JUnit, then I want to get a reference to ParentSuite.class. Is this possible?
There is the TestWatcher rule that gets you an instance of Description, which is kind of in the right direction, but that does not include the suite class.
I know this is probably not the best way to write unit tests. My original problem is to run a validation on all classes that are in the project under test, but not those of the dependencies. The TestCase will be in a dependency and included by test suites in other projects. The only solution I could think of is filter those classes with the same source location as that of the top-most-suite. To make that more clear:
BaseLibrary
* contains TestCase and TestSuite
* has classes that should not be validated
ConsumerProject
* has a test-scoped and test-classified dependency to BaseLibrary
* contains ParentSuite
* has classes that should be validated
You probably want to use JUnit #Category https://github.com/junit-team/junit/wiki/Categories
Here's a blog on how to make Categories https://weblogs.java.net/blog/johnsmart/archive/2010/04/25/grouping-tests-using-junit-categories-0
This way you can make Categories for each of your projects.
public interface ConsumerProject {}
Then you can use the #Category annotation to mark test classes (or even test methods) as being in particular categories:
#Category(ConsumerProject.class)
public class TestCase { ... }
Then your suites can be set up to run all the tests for particular categories
#RunWith(Categories.class)
#IncludeCategory(ConsumerProject.class)
#SuiteClasses( { ....})
public class ConsumerProjectSuite { }
You can even have the same test get marked with multiple categories
#Category({ConsumerProject.class, OtherProject.class})
public class CommonTests { }

How to start JUnit tests separately?

I am new in JUnit and I found a lot of examples in web, but all of them show me a class of tests, where they start in sequence. I have the follow test class:
public class ControlServiceTest {
#Test
public void testCreateUser() {
//some stuff
}
#Test
public void testLoginUser() {
//some stuff
}
}
But i need to start only one test at same time, not both. I will be glad if somebody explain me how can I do it.
If you're using Eclipse:
Right click on the specific test that you want to run in Outline, Run As -> JUnit Test.

How do I make a junit white list of tests to run

I'm working on writing unit tests for a class that I'm developing. Another developer is developing other tests for the same class for methods that he's developing. So our tests find themselves in the same JUnit test class.
So what I wanted to do was to set up a test suite to run just my tests while I'm developing as a temporary measure. I created a Category for my tests and have marked them as such. I then created a class to be my test suite. I told it to include tests that belong to this category. When I run it, it still runs everything. There are a lot of tests, so it would be tedious to mark all the tests I don't want ran with #Ignore. Is there a way to say, run only the tests in a category but none else?
You can write a wrapper test class which method calls the main test class (only your method), then run Junit tests on the wrapper class.
public class MainTestClass {
#Test
public void yourFirstTest() {
...
}
#Test
public void yourSecondTest() {
...
}
#Test
public void otherFirstTest() {
...
}
}
public class WrapperTestClass {
#Test
public void yourFirstTest() {
new MainTestClass().yourFirstTest();
}
#Test
public void yourSecondTest() {
new MainTestClass().yourSecondTest();
}
}
I think you can implement your own 'org.junit.runner.RunWith' and then annotate your test class to use it as necessary.
#RunWith(MyRunnerClass.class)
Note: The correct solution here is in the above comments regarding code branches etc.

Injecting & Configuring Gradle Builds

I'm reading up on Gradle and am very interested in it, specifically because (it appears) that it allows the introduction of inheritance into the build process. For instance, if I have a Java web app that might be packaged and deployed to Google App Engine instances as well as Amazon EC2 instances, I need a sophisticated build that can take the same Java, XML, PROPERTIES, CSS and image files and package/deploy them into 2 drastically-differently packaged WAR files.
GAE apps are very specific as to how they are packaged; EC2 (pretty much) just require that you conform to servlet specs. GAE apps get "deployed" by running an update command from the appcfg.sh script that comes with your SDK; EC2 has their own way to deploy apps. The point is, they are very different packaging/deployment processes for both PaaS providers:
public abstract class PackageTask {
// ...
}
// Package my Eclipse project for deployment to GAE.
public class AppEnginePackageTask extends PackageTask {
// ...
}
// Package my Eclipse project for deployment to EC2 instances.
public class AmazonPackageTask extends PackageTask {
// ...
}
public abstract class DeployTask {
// ...
}
// Deployment to GAE.
public class AppEngineDeployTask extends DeployTask {
// ...
}
// Deployment to EC2.
public class AmazonDeployTask extends DeployTask {
// ...
}
Then, I might have a myapp.gradle buildfile that templates the build order of tasks:
clean()
compile()
package()
deploy()
...and somehow, I can configure/inject AppEnginePackageTask/AppEngineDeployTask in place of package()/deploy() for a GAE-based build, or I can configure/inject AmazonPackageTask/AmazoneDeployTask into those templated tasks. Again, I'm not sure how to do this (or even if Gradle can do this), but it's what I'm after.
My understanding was that Gradle can do this. Ant can also be forced to have highly-modular, elegant builds that work this way, but being XML-based, it takes some finessing, whereas an OOP-based language like Groovy makes this cleaner and simpler.
However, all the examples I see of Gradle tasks take the following form:
task package(dependsOn: 'compile') {
// ...
}
task deploy(dependsOn: 'package') {
// ...
}
So I ask: these look/feel like non-OOP task definitions. Is my understanding of Gradle (and its OOP nature) fundamentally incorrect? What am I missing here? How can I accomplish these notions of "configurable/injectable build templates" and inheritance-based tasks? Thanks in advance!
Edit I re-tagged this question with "groovy" because Gradle buildscripts are written in a Groovy DSL, and someone who happens to be a Groovy-guru (say that 5 times fast) might also be able to chime in even if they know little about Gradle.
As described here, there are simple tasks and enhanced tasks. The latter are much more flexible and powerful.
The following example isn't exactly what you describe, re:injection, but it illustrates OOP.
Here is the sample build.gradle file. It avoids "package" as that is a keyword in Java/Groovy. The 'build' target depends on 'compile' and some flavour of 'doPack', depending on a property called 'pkgTarget'.
task compile << {
println "compiling..."
}
task build() << {
}
build.dependsOn {
compile
}
build.dependsOn {
if (pkgTarget == "Amazon") {
task doPack(type: AmazonPackageTask)
} else if (pkgTarget == "Google") {
task doPack(type: GooglePackageTask)
} else {
task doPack(type: MyPackageTask)
}
}
where the tasks are defined later in the same file. (Per doc, this code can go into a "build src" directory):
// -----
class MyPackageTask extends DefaultTask {
def init() { println 'common stuff' }
#TaskAction
def doPackage() {
println 'hello from MyPackageTask'
}
}
class AmazonPackageTask extends MyPackageTask {
#TaskAction
def doPackage() {
init()
println 'hello from AmazonPackageTask'
}
}
class GooglePackageTask extends MyPackageTask {
#TaskAction
def doPackage() {
init()
println 'hello from GooglePackageTask'
}
}
and here is the gradle.properties file:
pkgTarget=Amazon

Categories

Resources