Running JUnits with JavaFX dependencies on Jenkins - unit-testing

I'm trying to setup pipeline on Jenkins for our JavaFX application. Everything works fine, but I have one problem by starting unit tests. Each test, which somehow uses JavaFX classes fails with following root cause:
Caused by: java.lang.IllegalAccessException: class net.bytebuddy.description.annotation.AnnotationDescription$ForLoadedAnnotation cannot access interface com.sun.javafx.beans.IDProperty (in module javafx.base) because module javafx.base does not export com.sun.javafx.beans to unnamed module #7ee955a8
I tried a following things:
setting env variable JAVA_OPTS
JAVA_OPTS=--module-path /path/to/javafx --add-modules javafx.controls,javafx.base
adding compiler options in gradle
tasks.withType(Test).configureEach {
doFirst {
options.compilerArgs += [
'--module-path', '/path/to/javafx',
'--add-modules', 'javafx.controls,javafx.base',
]
classpath = files()
}
}
but nothing changed. I'm using the OpenJDK compiled by Azul. I took the version with JavaFX (JDKFX) but I'm not able to make this tests running (tests without any references to JavaFX are running fine). I'm also able to compile the application. Do you have any sugestions?

The problem was, like mentioned in comments, that it should not be added to the compilerArgs but to the runtime and additionally I placed it in wrong build.gradle file. The final configuration which solved all problems was to add following to the main build.gradle file:
allprojects {
tasks.withType(Test).configureEach {
jvmArgs += [
'--add-modules', 'javafx.controls,javafx.base,javafx.graphics',
'--add-opens', 'javafx.graphics/com.sun.javafx.application=ALL-UNNAMED',
'--add-opens', 'javafx.base/com.sun.javafx.beans=ALL-UNNAMED',
]
}
}

Related

Testing base code with wasm-pack test throws "use of undeclared crate or module" error

Could someone tell me what I'm doing wrong here ? I've written script entries in package.json, which one for tests looks like this
"test:headless": "cross-env RUSTFLAGS=\"-C target-feature=+atomics,+bulk-memory,+mutable-globals,+simd128\" rustup run nightly-2022-04-07 wasm-pack test --headless --chrome -- -Z build-std=panic_abort,std",
altought executed test cannot recognize wasm-rayon namespace which is my base code.
here is code to repo: https://github.com/MalwareX95/wasm-playground
I had to add rlib in crate-type: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/template-deep-dive/cargo-toml.html
We also specify crate-type = ["rlib"] to ensure that our library can be unit tested with wasm-pack test.

Robolectric unit tests using legacy instead of binary resources only when running multi-module unit test run config

I have a multi-module android project. I have a bunch of unit tests in each module and I have always been able to run them all at once using a run configuration like this one:
Many of my tests use a base class that runs with RobolectricTestRunner. This base class looks like this:
#RunWith(RobolectricTestRunner::class)
#Config(application = AndroidTest.ApplicationStub::class,
manifest = Config.NONE,
sdk = [21])
abstract class AndroidTest {
#Suppress("LeakingThis")
#Rule #JvmField val injectMocks = InjectMocksRule.create(this#AndroidTest)
fun application(): Application = ApplicationProvider.getApplicationContext()
internal class ApplicationStub : Application()
}
**When running these tests using the above config, I get the error **
[Robolectric] NOTICE: legacy resources mode is deprecated; see http://robolectric.org/migrating/#migrating-to-40
This makes many of my tests fail with ResourceNotFoundException
However, when I run tests only in a specific module, everything passes. This is because Robolectric now uses Binary resources:
[Robolectric] sdk=21; resources=BINARY
I have followed the migration instructions in build.gradle files for each module, having added the following in each android block:
testOptions {
unitTests {
includeAndroidResources = true
returnDefaultValues = true
}
}
One clue I have found but have been unable to fix is this when I run the ALL UNIT TEST task:
WARNING: No manifest file found at build/intermediates/merged_manifests/debug/../../library_manifest/debug/AndroidManifest.xml.
Falling back to the Android OS resources only.
No such manifest file: build/intermediates/merged_manifests/debug/../../library_manifest/debug/AndroidManifest.xml
To remove this warning, annotate your test class with #Config(manifest=Config.NONE).
I have tried, as you have seen, to add the manifest=Config.NONE, which had no effect (and is now deprecated anyway).
Edit: Also tried android.enableUnitTestBinaryResources = true in settings.gradle, but this prevents the app from building due to it being a deprecated flag in the current gradle tools.
Thanks for any help provided!
So with the default unit test run platform being changed to Gradle in Android Studio, I managed to figure out a way to run unit tests in multiple modules all at once, circumventing the Robolectric bug.
First, go into run configurations and create a new Gradle Config.
Then, as the gradle project, select the top level project.
For arguments, use --tests "*"
And now for the gradle tasks, this is a little bit more error-prone. Here is an example of how I have it setup for my project:
:androidrma:cleanTestGoogleDebugUnitTest :androidrma:testGoogleDebugUnitTest
:calendar:cleanTestDebugUnitTest :calendar:testDebugUnitTest
:gamification:cleanTest :gamification:test
:player:cleanTest :player:test
:playlists:cleanTest :playlists:test
:sleepjournal:cleanTest :sleepjournal:test
:sound-content-filters:cleanTest :sound-content-filters:test
Please note that I inserted new lines between each module for more clarity here, in the tasks, just separate each entry with a space.
For your app module, in my case named androidrma, you must use your build variants name in the cleanTestUnitTest and testUnitTest , in my case being GoogleDebug.
If we look at the calendar module, it is an android module, , so it still operates with the same logic as the appModule.
However, if you look at player, playlists, sleepjournal, etc. those are pure kotlin modules. The tasks thus differ in their syntax.
Once you have entered all this information and everything is functioning, I recommend checking "store as project file" checkbox at the top right of the run config setup screen.
This works in Android Studio 4.2 as well as Arctic Fox, haven't tested on other versions.

How to create separate tests with Gradle and Kotlin?

I am working on a Kotlin project with Gradle that includes unit tests. I want to add some integration tests (or functional tests, never understood the difference between the two), but I want to be able to run them independently. Ideally, the source of the tests are in different folders.
I am using Gradle 4.5 and my build.gradle file looks something like this :
buildscript {
ext.kotlin_version = '1.2.21'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName = 'xyz.bobdudan.myproject.AppKt'
repositories {
maven { url "http://maven.stardog.com" }
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testCompile 'io.kotlintest:kotlintest:2.0.7'
}
I have tried the method described here for java, but it doesn't work : the task also runs the unit tests, but they can't be found, and the integration tests are not executed at all.
What can i do ?
Edit :
Here is the result of gradle clean integTest with the solution of #lance-java:
:clean
:compileIntegTestKotlin
:compileIntegTestJava NO-SOURCE
:processIntegTestResources NO-SOURCE
:integTestClasses UP-TO-DATE
:integTest NO-SOURCE
Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
See https://docs.gradle.org/4.5/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed
So nothing is executed (I make sure that the tests are supposed to fail)
Note: I'm not a kotlin dev so will write in groovy.
You can add another SourceSet which will automatically add a JavaCompile task for the SourceSet and also a few Configuration instances to the model (eg integTestCompile, integTestCompileOnly, integTestRuntime etc)
sourceSets {
integTest {
java.srcDir 'src/integTest/java'
resources.srcDir 'src/integTest/resources'
}
}
configurations {
integTestCompile.extendsFrom compile
}
Then you can add another Test task
task integTest(type: Test) {
testClassesDir = sourceSets.integTest.output.classesDir
classpath = sourceSets.integTest.runtimeClasspath
}
You may wish to wire the integTest task into the normal DAG, or perhaps you'll leave this off and call it explicitly
check.dependsOn integTest
To tell long story short you have to:
create separate source sets,
create testTask for each test source,
set it up,
define order these tasks should be executed during build/check
and you are good to go.
Here is a guide in an answer to another question about how to do this for project using JUnit5 and Kotlin Spek test framework.

TestStack White - Run tests from command line

I'm looking for a solution to start my tests from command line.
I created a UnitTest Procjet in VisualStudio2017 for my .NET solution.
Added TestStack.White NuGet package to the project.
The test are running fluently when I start from the VisualStudio2017.
I would like to start it from Jenkins also. I think it is the easiest to do it from command line, so I add it to my pipeline configuration (Jenkinsfile)
stage('Run UI Tests') {
steps {
bat('"C:\\PATH_TO_MSTEST\\mstest" /testcontainer:PATH_TO_MY_TEST_PROJECT\\bin\\Debug\\MyTests.dll')
}
}
When I try to start it from cmd like I would do with with regular Unit Tests, it is not working.
It says:
Starting execution...
No tests to execute.
I build the project before I start 'Run UI Tests' stage.
Any ideas how to make it work? Could really find it on stackoverflow, github issues of TestStack nor other glory places on the web
Found a solution.
On my local developer machine it was working, the mstest version was 14
On the build agent machine the mstest version was 15, that was not working somehow (it had nothing to do with TestStack White, simply the unit tests were not working)
What I do is, calling vstest.console.exe instead of the mstest.
C:\Program Files (x86)\Microsoft Visual Studio\2017\TestAgent\Common7\IDE\Extensions\TestPlatform\vstest.console.exe
So, instead of
stage('Run UI Tests') {
steps {
bat('"C:\\PATH_TO_MSTEST\\mstest" /testcontainer:PATH_TO_MY_TEST_PROJECT\\bin\\Debug\\MyTests.dll')
}
}
My command in the Jenkinsfile was:
stage('Run UiTests') {
steps {
bat('"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\TestAgent\\Common7\\IDE\\Extensions\\TestPlatform\\vstest.console.exe" PATH_TO_MY_TEST_PROJECT\\bin\\Debug\\MyTests.dll')
}
}
nunit3-console is great alternative to MSTEST. Please refer below link.
e.g.
nunit3-console \bin\Debug\Automation.dll --where "cat=Smoke-Tests"
https://github.com/nunit/docs/wiki/Console-Command-Line

Using Reflection Causing MissingMethodException in Xamarin UITest

I have a class in my Xamarin PCL which makes a call to System.Reflection.GetRuntimeProperties. For an example, let's say my PCL class has this method:
public string ExampleMethod(string arg) {
if(arg == null) return null;
IEnumerable<PropertyInfo> infos = this.GetType().GetRuntimeProperties();
return infos[0].Name;
}
I then have a Xamarin.UITest project which references the PCL project and tests this class. I have two test cases in my TestFixture so far, which for our example would be the following:
[Test]
public void TestExampleMethod_ArgNull_Null(){
Assert.That (exampleInstance.ExampleMethod(null), Is.Null);
}
[Test]
public void TestExampleMethod_ArgNotNull_NotNull(){
Assert.That (exampleInstance.ExampleMethod("testValue"), Is.NotNull);
}
When I run the Xamarin.UITest project, it compiles, runs the tests, and completes fine on both Android and iOS platforms. The TestExampleMethod_ArgNull_Null test passes since it returns early. However, the TestExampleMethod_ArgNotNull_NotNull test fails with:
System.MissingMethodException : Method 'RuntimeReflectionExtensions.GetRuntimeProperties' not found.
So it appears that even though everything is compiling just fine, and I am able to run other test cases fine, the Xamarin.UITest project is not able to use anything in System.Reflection. Does anyone know how I go about debugging this?
On my end, using the following failed to build:
IEnumerable<PropertyInfo> infos = this.GetType().GetRuntimeProperties();
return infos[0].Name;
due to not being able to do bracket indexes on and IEnumerable. I changed to this:
List<PropertyInfo> infos = this.GetType().GetRuntimeProperties().ToList();
return infos[0].Name;
And the project built and the tests ran successfully.
The class with the method using Reflection was in a PCL which was referenced from a UI Test project.
So basically I am not able to reproduce the error you got.
I posted this to Xamarin Support as well (thanks #jgoldberger) and we were able to figure out that it was due to a project setup issue. This is a project which uses Couchbase Lite which requires a specific version of Json.Net (6.0.4 as of this post). I must have accidentally updated the packages on some of the projects since the same version of Json.Net was not being used across all the projects (PCL, Android, iOS, and UITest). I ended up re-creating the project from scratch and that took care of it.