Skip to content

Instantly share code, notes, and snippets.

@alexlafroscia
Last active December 21, 2020 10:31
Show Gist options
  • Save alexlafroscia/c6757de349b27e34eff6 to your computer and use it in GitHub Desktop.
Save alexlafroscia/c6757de349b27e34eff6 to your computer and use it in GitHub Desktop.
JUnit Testing with Gradle
/*
* This build file was auto generated by running the Gradle 'init' task
* by 'alex' at '1/27/15 7:02 PM' with Gradle 2.2.1
*
* This generated file contains a commented-out sample Java project to get you started.
* For more details take a look at the Java Quickstart chapter in the Gradle
* user guide available at http://gradle.org/docs/2.2.1/userguide/tutorial_java_projects.html
*/
// Apply the java plugin to add support for Java
apply plugin: 'java'
apply plugin: 'jacoco'
// In this section you declare where to find the dependencies of your project
repositories {
jcenter()
}
// In this section you declare the dependencies for your production and test code
dependencies {
compile 'org.slf4j:slf4j-api:1.7.7'
// JUnit and Mockito
testCompile "junit:junit:4.11"
testCompile "org.mockito:mockito-core:1.+"
}
jar {
manifest {
attributes 'Main-Class': 'com.laboon.CoffeeMaker'
}
}

JUnit Testing with Gradle

By Alex LaFroscia and Will Engler


Gradle Setup

0. Install Gradle

  1. Mac OSX

    brew install gradle
    

    If you need to install Homebrew (which gives you the brew command) you can find out more about it here.

  2. Ubuntu

    sudo add-apt-repository ppa:cwchien/gradle
    sudo apt-get update
    sudo apt-get install gradle
    

1. Establish your project as a Gradle project

$ cd path/to/your/project
$ echo ".gradle/" >> .gitignore
$ echo "build/" >> .gitignore
$ gradle init

2. Move your project to the right directory

Gradle expects your .java files to be in src/main/java, so for CoffeeMakerQuest you'll need to do something like this:

mkdir -p src/main/java
mv *.java src/main/java

This allows Gradle to find the right files when it's trying to build your .jar file.

3. Set up your build.gradle file

This is where Gradle will find most of its configuration information. The default one is a good starting place. The one I'm using is attached.

One thing you have to make sure you do is tell Gradle where your main() method is. For CoffeeMakerQuest, that looks like this:

jar {
    manifest {
        attribute 'Main-Class': 'com.laboon.CoffeeMaker'
    }
}

4. Add your tests

Gradle looks for tests in src/test/java. You can link against JUnit or Mockito like you noramally would, if they were in your classPath, using

import static org.junit.Assert.*;
import org.junit.*;

etc.

Gradle Commands

Build the Executable

$ gradle build

Outputs a .jar file to build/lib

Run the Tests

$ gradle test

Runs JUnit tests on your code (by default). Outputs an HTML file with test results to build/reports/tests/index.html.

Code Coverage Report

$ gradle jacoco

Outputs a code coverage report to build/reports/jacoco/test/html/index.html. The path is obnixous, but at least it works.

Troubleshooting

Note about running Gradle commands: Sometimes the commands need to do some initial setup (installing dependencies, etc) the first time they are run. I had a lot of trouble getting JaCoCo to work initially because it couldn't find the JaCoCo executable. Two things have I've found helpful are:

  1. Running Gradle through the gradlew wrapper script that is generated by the initial setup command (see step 1 above)

    It seems like sometimes this will download dependencies that are not downloaded if you just use gradle. If anyone knows more about this, please comment below and I'll update this guide.

    An example of running a command with the wrapper would be doing

    $ ./gradlew test
    

    instead of

    $ gradle test
    

    The wrapper will always work, even if you're not having trouble.

  2. Destroy your build/ directory

    This is fine because all of the files are generated by the Gradle commands. If you notice in step 1 above, we don't even keep the build/ directory under source control. I found with JaCoCo that it assumed the executable existed because build/ existed, even though it hadn't been downloaded yet. Deleting it and starting again without a build/ directory got things working right.

JaCoCo gets "skipped"

  1. Try running with the "wrapper" (./gradlew instead of gradle)
  2. Try deleting the build/ directory

Todo

  • Code Coverage in Test Report
  • Don't have Syntastic/other linters show errors all over the tests

Using Selenium

Adding Selenium to your Gradle setup is actually quite simple. The required changes are covered below.

build.gradle

To add Selenium to your dependencies, add mavenCentral() to your repositories and Selenium as a dependency, so that

// OLD
repositories {
    jcenter()
}

dependencies {
    compile 'org.slf4j:slf4j-api:1.7.7'

    testCompile "junit:junit:4.11"
    testCompile "org.mockito:mockito-core:1.+"
}

becomes

// NEW
repositories {
    jcenter()
    mavenCentral()
}

dependencies {
    compile 'org.slf4j:slf4j-api:1.7.7'

    // JUnit and Mockito
    testCompile "junit:junit:4.11"
    testCompile "org.mockito:mockito-core:1.+"
    
    // Selenium
    testCompile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.+'
}

Test Files

Now, your test files just need to import the correct files. An example of a working Selenium test would be something like this:

package com.SoftwareTesting;

import junit.framework.TestCase;
import static org.junit.Assert.*;
import org.junit.*;
import java.util.*;
import org.openqa.selenium.*;
import org.openqa.selenium.htmlunit.*;

public class ShowRepoTests extends TestCase {

  private WebDriver driver;

  /**
   * Set up a browser instance.
   */
  public void setUp() throws Exception {
    this.driver = new HtmlUnitDriver();
    this.driver.get("http://www.foo.com/bar");

    // Log a user in
    WebElement usernameForm = this.driver.findElement(By.id("login_field"));
    WebElement passwordForm = this.driver.findElement(By.id("password"));

    usernameForm.sendKeys("foo");
    passwordForm.sendKeys("bar");

    usernameForm.submit();
  }

  /**
   * Tear down the browser instance.
   */
  public void tearDown() throws Exception {
    this.driver.quit();
  }


  @Test
  public void testVisitingExistingRepo() {
    this.driver.get("http://www.foo.com/bar/baz");
    assertEquals("Page name matches expected value", this.driver.getTitle(), "foobarbaz");
  }


  @Test
  public void testVisitingNonExistingRepo() {
    this.driver.get("http://www.foo.com/bar/" + UUID.randomUUID().toString());
    assertEquals("Page name matches expected value", this.driver.getTitle(), "Not found");
  }


}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment