I have a Gradle-based project in Eclipse which I want to test using JUnit 5. It does not have any tests right now, so I wanted to add a dummy one (e.g., assertEquals(true, true)) to make sure that Gradle can run the test.
However, I experience two problems:
1) When I want to create JUnit test case as "Project Right Click --> New --> JUnit Test Case", it creates a test case inside /src directory. See the image below:
2) When I try to build my Gradle configuration, I get the following output:
> Task :compileJava FAILED
/home/.../src/main/java/TestFoo.java:1: error: package org.junit does not exist
import static org.junit.Assert.*;
^
As far as I understand, the test case cannot resolve the package org.junit. At the same time, Eclipse does not let me create a proper JUnit test case in the proper /test directory.
What do you think could be a possible solution here? I tried finding a way to override default test directory, but could not find any way to do that.
P.S. This is not duplicate as I tried this and I have all dependencies declared. The following snippet is the build.gradle contents (I apologize, but I cannot display all of its contents due to confidentiality reasons):
...
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
...
testCompile group: 'junit', name: 'junit', version: '4.12'
// Reference: https://www.baeldung.com/junit-5-gradle
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
}
run {
...
}
test {
useJUnitPlatform {
includeTags 'fast'
excludeTags 'slow'
}
}
shadowJar {
mergeServiceFiles()
manifest {
attributes 'Implementation-Title': rootProject.name
attributes 'Implementation-Version': rootProject.version
attributes 'Implementation-Vendor-Id': rootProject.group
attributes 'Created-By': 'Gradle ' + gradle.gradleVersion
attributes 'Main-Class': mainClassName
}
archiveName rootProject.name + '-' + rootProject.version + '.jar'
}
You can either use this: How to create unit tests easily in eclipse (answer with most upvotes)
Or install this plugin: https://moreunit.github.io/MoreUnit-Eclipse/ (and create test using Ctrl + J)
Related
I am trying to integrate and setup the JUnit 5 libraries with IntelliJ on my linux distro. I added JUnit to my gradle, and built it using gradle. But I am still seeing an error on my unit tests prompting me to "add junit to my classpath" even though it already is.
Here is my build.gradle
id 'java'
id 'idea'
}
group 'com.techchallenge'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.junit.jupiter:junit-jupiter:5.4.2'
testCompile('org.junit.jupiter:junit-jupiter-api:5.3.1')
testCompile('org.junit.jupiter:junit-jupiter-engine:5.3.1')
}
test {
useJUnitPlatform()
}
UPDATE
See screenshot. I added the dependency and it is still prompting me to add the junit to my classpath though I already did
UPDATE 2
I updated the build.gradle and also did gradlew clean build test which was successful. But it is still showing the error with my junit annotations- and keeps prompting me to add junit 5.4 to my classpath though it is there.
id 'java'
id 'idea'
}
group 'com.techchallenge'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.junit.jupiter:junit-jupiter:5.4.2'
implementation 'org.junit.jupiter:junit-jupiter:5.4.2'
implementation 'org.junit.jupiter:junit-jupiter:5.4.2'
implementation 'org.junit.jupiter:junit-jupiter:5.4.2'
implementation 'org.junit.jupiter:junit-jupiter:5.4.2'
implementation 'org.junit.jupiter:junit-jupiter:5.4.2'
implementation 'org.junit.jupiter:junit-jupiter:5.4.2'
testCompile('org.junit.jupiter:junit-jupiter-api:5.4.2')
testRuntime('org.junit.jupiter:junit-jupiter-engine:5.4.2')
testRuntime('org.junit.vintage:junit-vintage-engine:5.4.2')
}
test {
useJUnitPlatform()
}
It should recognise your setup. You may try adding junit5 dependencies (which is how junit5 is added creating a Gradle project from scratch using IntelliJ's New Project option) as below then reload your Gradle Project.
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}
You may try File | Invalidate caches/Restart... option to get rid of odd issues if your project runs tests successfully using gradle test cli command
https://www.jetbrains.com/help/idea/invalidate-caches.html
You have to use the right imports for Junit 5, You are using Junit4 imports. Since version 5 #Test, Assertions, etc are within org.junit.jupiter.api package. e.g:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class DummyTest {
#BeforeEach
void setUp() {
}
#AfterEach
void tearDown() {
}
#Test
void name() {
Assertions.assertTrue(true);
}
You may look into junit5-jupiter-starter-gradle
I had a similar problem with JUnit 5 using Maven. I discovered that IDEA had created some *.iml files where it should not have. I had one in the test folder called test.iml. After deleting them the problems went away.
Please check if IDEA did not create some sneaky modules unexpectedly.
I see in the screenshot that you have one of those:
My advise is to delete it.
Make sure you have correctly setup gradle inside your intellij like for maven
and make sure You have installed JUnit plugin for IntelliJ IDEA,
you can even point gradle to your local repository like
repositories {
flatDir {
dirs 'C:/path/to/local/directory'
}
}
dependencies {
compile name: 'name-of-jar'
}
I cannot run tests via Gradle in IntelliJ IDEA because of "No tests found for given includes" error.
How can I fix it?
GradleTests
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class GradleTests {
#Test
public void initTest() {
assertTrue(true);
}
}
build.gradle
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
//testCompile group: 'junit', name: 'junit', version: '4.12'
// https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.6.0'
}
test {
useJUnitPlatform()
}
Error:
> Task :test FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':test'.
> No tests found for given includes: [GradleTests.initTest](filter.includeTestsMatching)
Some notes:
Issue is reproduced with both JUnit 4 and 5
IntelliJ IDEA 2019.3.3 (Community Edition), Build #IC-193.6494.35, built on February 11, 2020
Test is in src/test/java
changing runner like Intelij 2019.1 update breaks JUnit tests didn't help
without useJUnitPlatform() result is the same
I had this error with a similar setup, but couldn't solve it with the previous answers. Resolved it by doing this.
File > Setting (Ctrl+Alt+S)
Build, Execution, Deployment > Build Tools > gradle
Run Tests using: Intellij IDEA
All credit to: https://linked2ev.github.io/devsub/2019/09/30/Intellij-junit4-gradle-issue/.
Thanks to Ben Watson I've found solution. Since JUnit 5.4.0 there is aggregate artifact with both api and engine dependencies. So just adding one dependency to build.gradle resolved this issue.
testCompile ('org.junit.jupiter:junit-jupiter:5.6.0')
Gradle has no idea where to look for tests. Add this to your app build.gradle file root(Not inside android or dependencies closure):
tasks.withType(Test) {
useJUnitPlatform()
testLogging { // This is for logging and can be removed.
events("passed", "skipped", "failed")
}
}
/app/build.gradle
android {
testOptions {
unitTests.all {
useJUnitPlatform()
}
}
}
Another cause of this behaviour when using IntelliJ to edit a Kotlin project is the folders used for the tests, Java classes need to be in a subfolder of java and Kotlin classes in a subfolder of kotlin.
Here's an example of a mini-project I created which demonstrates the folder structure https://github.com/znsio/AutomatedTestingWithKotlin/tree/main/src/test
I found the explanation which is quoted below together with the link to the source:
"My problem was in single path to kotlin and java tests. So kotlin tests are in root/src/test/kotlin/package and they are running fine with gradle :cleanTest :test and java tests must be in root/src/test/java/package. Otherwise neither compileTestKotlin nor compileTestJava will not find java tests to compile."
https://discuss.kotlinlang.org/t/not-able-to-run-unit-tests-on-kotlin-multiplatform-project/15779/7
Gradle is case sensitive in choosing its selector. See here You may need to change "GradleTests" to "gradleTests"
I've got an Error: No tests found for given includes: ... (filter.includeTestsMatching).
After I checked JUnit dependency I discovered junit-4.13.1 version.
Fixed with replacing this dependency to org.junit.jupiter.api-5.7.0.
In my case, I had the wrong import.
I needed import org.junit.jupiter.api.Test; instead of import org.junit.Test;
Make sure that the test method is granted public access.
After going through all configurations and finding nothing, a simple gradle clean fixed this very persistent issue for me, and i could keep using "run tests with gradle".
./gradlew :domain:test --tests "..."
> Task :domain:test FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':domain:test'.
> No tests found for given includes: ...
./gradlew clean
./gradlew :domain:test --tests "..."
BUILD SUCCESSFUL in 8s
My problem was the filename that contained the test class did not match the class name. So I had AppRepositoryTest.kt with FetchDataUseCaseTest test class inside. Apparently Junit 4 does not like that, so once I made both names the same it started working.
I attempted to create a normal Kotlin project (non-android, just desktop/command line project) with Android Studio 2.3.3.
I followed the steps as laid out here but with different build.gradle content whose content I shared here.
Actually that content of build.gradle I copied from build.gradle file after generating a new project with IntelliJ Community Edition (2017.2).
Then I create a configuration to be able to run it on desktop with proper set up like Main Class, Working directory, and Use classpath of module. You can see in the image below.
and following is the project file structure I have
Then I sync the project, it succeeds. But error kicks in when I try to Run the project. I got the following error.
"/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java" -Didea.launcher.port=7534 "-Didea.launcher.bin.path=/Applications/Android Studio.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/charsets.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/localedata.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/sunec.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/jce.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/jsse.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/management-agent.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/resources.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/rt.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/lib/dt.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/lib/jconsole.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/lib/sa-jdi.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/lib/tools.jar:/Users/haxpor/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar:/Users/haxpor/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.1.4-2/272a21c30432c943d618008fbbd34762eb0d6c8a/kotlin-stdlib-jre7-1.1.4-2.jar:/Users/haxpor/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.1.4-2/fec983b2608a8a91a1b87dba18d247d692cf6b51/kotlin-stdlib-1.1.4-2.jar:/Users/haxpor/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.1.4-2/168cc3f45c307edda6c867dd0635a7d451257551/kotlin-stdlib-jre8-1.1.4-2.jar:/Applications/Android Studio.app/Contents/lib/idea_rt.jar" com.intellij.rt.execution.application.AppMain io.wasin.testjavaapp.Main
Exception in thread "main" java.lang.ClassNotFoundException: io.wasin.testjavaapp.Main
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:123)
Process finished with exit code 1
I saw the classpath parameter as supplied in above /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java has no related directory to my project. I don't know how to add classpath directory via gradle despite I set up it in configurations already.
How can I solve this problem?
Update:
The following is my Main.kt code. It's just for testing purpose. So just printing something out.
package io.wasin.testjavaapp
object Main {
#JvmStatic fun main(arg: Array<String>) {
println("Hello world")
}
}
Also I updated build.gradle for Kotlin version to match the version of Kotlin plugin on Android Studio. It's now ext.kotlin_version = '1.1.4-2'. Although still doesn't solve the problem.
Update 2
I checked inside build directory at the same level of src directory. There are no .class or intermediates files generated/built over there, only kotlin-build/caches/version.txt and that's it. No other files. So the problem might be due to the source files are not compiled at all?
Update 3
I tried creating a new module to see if it's the root cause or not. Also created assets folder just to act as Working Directory, rearranged source folder again to be as following.
We now have 2 modules.
testJavaApp - root one
desktop - consists of Main.kt and used as desktop executable
testJavaApp has the following code for build.gradle
group 'io.wasin'
version '1.0-SNAPSHOT'
// Top-level build file where you can add configuration options common to
all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.1.4-2'
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
also desktop module has following code for build.gradle
apply plugin: 'kotlin'
sourceSets.main.java.srcDirs = [ "src/" ]
project.ext.mainClassName = "io.wasin.testjavaapp.Main"
project.ext.assetsDir = new File("../assets");
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
repositories {
mavenCentral()
}
task run(dependsOn: classes, type: JavaExec) {
main = project.mainClassName
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
workingDir = project.assetsDir
ignoreExitValue = true
}
Unfortunately, it still didn't work and it's the same error that shown up.
Update 4
#aristotll provided info in a comment that he tested with Android Studio and faced the same problem, but not with IntelliJ. He said it might be Android Studio bug. So I guess, I would try a few more times then decide whether it's solid enough to report as a bug. Thanks for taking time to testing out.
I also met this problem and solved it.
Add runtimeClasspath files("build/classes/kotlin/main") in build.gradle
dependencies {
// This dependency is found on compile classpath of this component and consumers.
compile 'com.google.guava:guava:23.0'
// Use JUnit test framework
testCompile 'junit:junit:4.12'
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile group: 'dom4j', name: 'dom4j', version: '1.6.1'
runtimeClasspath files("build/classes/kotlin/main")
}
because Android Studio doesn't find classes in build/classes/kotlin/main. Add runtimeClasspath and it works!
I'm trying to run ./gradlew build for a nested multi project structure and I'm running into issues that only seem to appear for projects with test source roots. Being new to both java and gradle I'm sure I'm breaking more than one convention, but I still think this should be working.
Essentially, all the dependencies seem to be added fine, but when I have one project that only has a Test srcDir that depends on another project that has a Test srcDir, it doesn't recognize packages/symbols in that root project. However, projects with regular srcDirs (not test) don't seem to have a problem.
My project has more going on than this, but here is the simplest setup I've tried that illustrates the problem.
My project structure:
qatests
/Applications
/AppGroupName
/AppBasePageObjects
/src
/AppBaseTests
/src
/BasePageObjects
/src
/BaseTests
/src
My settings.gradle in qatests:
rootProject.name = 'QaTests'
include 'BasePageObjects'
include 'BaseTests'
include 'Applications:AppGroupName'
include 'Applications:AppGroupName:AppBasePageObjects'
include 'Applications:AppGroupName:AppBaseTests'
My build.gradle in qatests:
version '1.0-SNAPSHOT'
allprojects {
repositories {
mavenCentral()
}
}
subprojects{
if(project.name.contains("Tests")){
apply plugin: 'java'
sourceCompatibility = 1.8
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.+'
}
if(project.name != "BaseTests")
{
println "$project.name depends on BaseTests"
dependencies {
testCompile project(':BaseTests')
}
}
sourceSets {
test {
java {
srcDir 'src'
}
}
}
}
if(project.name.contains("PageObjects")){
apply plugin: 'java'
sourceCompatibility = 1.8
dependencies {
compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.+'
}
if(project.name !="BasePageObjects")
{
dependencies {
compile project(':BasePageObjects')
}
}
sourceSets {
main {
java {
srcDir 'src'
}
}
}
}
}
I won't include my build.grade for the BaseTest project since that seems to compile fine during the gradlew build, but here is my build.gradle for AppBaseTests:
version '1.0-SNAPSHOT'
dependencies {
compile 'org.apache.commons:commons-lang3:3.4'
compile project(':Applications:AppGroupName:AppBasePageObjects')
}
When I run ./gradlew build in the qatests root, the BaseTests, BasePageObjects, and AppBasePageObjects projects seem to compile fine and AppBasePageObjects successfully uses packages and symbols from BasePageObjects. For some reason however, AppBaseTests can't seem to recognize packages and symbols in BaseTests.
If I clone this project from scratch, IntelliJ runs the gradle scripts scripts automatically and everything seems to work out of the box just fine with the dependencies, so this just confuses me even more.
I've tried adding compile and testcompile for all the project dependencies since that's the only real difference between AppBasePageObjects which works and AppBaseTests which doesn't work. I've also tried adding compileJava.dependsOn(':BaseTests:build') to the AppBaseTests build.gradle file. And a few other rabbit holes, but nothing seems to have any effect on this dependency issue.
For what it's worth, here is the first error I see in the actual build:
error: package Tests does not exist import Tests.BaseTest;
Any help or suggestions are greatly appreciated. If you would like to distribute some harsh insults I'll take those as well. Thank you.
I believe I found an answer while reading another solution here:
Multi-project test dependencies with gradle
It seems I needed to use testCompile project(':BaseTests').sourceSets.test.output for command line builds as well as testCompile project(':BaseTests') for IDE functionality in my root build.gradle file. This only seems to be required for the test projects.
Here are the actual changes in my root build.gradle file:
if(project.name != "BaseTests")
{
println "$project.name depends on BaseTests"
dependencies {
testCompile project(':BaseTests')
testCompile project(':BaseTests').sourceSets.test.output
}
}
This seems a bit hacky but works, if somebody has a more thorough and intelligent answer please post!
I basically want to do something simple - or atleast i think it should be pretty simple.
My goal is to create an Intellij gradle project, add some dependencies to the module using gradle and add some java source code to it.
Then I just want to have an option to somehow compile the whole thing into 1 jar, containing all grade dependencies and being able to execute using "java -jar"
However it turned out that this is not as easy is i had thought.
I just created a new gradle project from intellij and added a Main class.
I´ll give you an overview over my files:
settings.gradle:
rootProject.name = 'gradleTestNewJar'
build.gradle:
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'application'
sourceCompatibility = 1.6
version = '1.0'
repositories {
mavenCentral()
}
mainClassName = "com.randomPackage.StarterClass"
dependencies {
compile 'org.seleniumhq.selenium:selenium-java:2.46.0'
testCompile group: 'junit', name: 'junit', version: '4.11'
}
main class:
package com.randomPackage;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
public class StarterClass {
public static void main(String[] args){
System.out.println("test");
WebDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_38);
driver.quit();
}
}
The main method of "MyStart" is executed when running from Intellij via debug.
So it works, when all dependencies get loaded correctly.
NOTE: I use Intellij Community Edition if this makes any difference.
What i tried:
1. I tried to just use "gradlew clean build".
This created a jar, but without libs.
But I didn´t expect it to be as easy as this.
2. I tried to build an artifact of the module as suggested here:
http://blog.jetbrains.com/idea/2010/08/quickly-create-jar-artifact/
I tried it with extracted and not extracted dependencies.
In both cases the dependencies were added into the jar, but they were added to the root of the jar.
When i tried to run the jar file via "java -jar", it complained:
"Exception in thread "main" java.lang.NoClassDefFoundError: org/openqa/selenium/WebDriver
..."
OK, so it couldn´t load the dependencies.
NOTE: I thought that the dependencies were not added to the classpath, but i am not sure about this. However, i would expect Intellij to add dependencies to the classpath( or declare in the manifest file)
3. I also tried to use the gradle application plugin.
However this creates a zip/tar which contains a execute script and a bin folder which was not my intention.
So i started googling for hours and hours but i cann´t find a solution to my problem.
Come on this cannot be so hard - it is just so basic.
I am sure some genius can help me out and point me to my - probably stupid - failure.
My current solution is as follows:
I use gradle to build a jar containing all libs, I do this witha custom task called fatJar.
Here is a part from my build.gradle
apply plugin: 'java'
jar {
manifest {
attributes("Manifest-Version": "1.0",
"Main-Class": "com.randomPackage.MainClass");
}
}
task fatJar(type: Jar) {
manifest.from jar.manifest
classifier = 'all'
from {
configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }
} {
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
with jar
}
Then I just execute "gradle fatJar" on the command line and get a perfect jar.