I have a few tests that have multiple annotations:
#Test
#LargeTest
#FlakyTest
I found a way to run only #LargeTest from here.
./gradlew app:connectedAndroidTest
-Pandroid.testInstrumentationRunnerArguments.size=large
Is there a way to run all Instrumentation Tests except those annotated as #FlakyTest?
android {
defaultConfig {
testInstrumentationRunnerArgument 'notAnnotation', 'android.test.suitebuilder.annotation.FlakyTest'
}
}
Related
So with the release of Android Studio Dolphin & Beta of Electric Eel, I wanted to try the instrumentation tests in gradle. I do however want to exclude some of the tests being run, in order to be able to run specific test suites one at a time.
So here is what I configured so far:
android {
testOptions {
managedDevices {
devices {
pixel2api30 (com.android.build.api.dsl.ManagedVirtualDevice) {
device = "Pixel 2"
apiLevel = 30
systemImageSource = "aosp-atd"
}
}
}
}
}
I know I can run my entire suite using
./gradlew device-nameBuildVariantAndroidTest
In my case that would be
./gradlew pixel2api30gaeDebugAndroidTest
gaeDebug being my build variant. This command is being run in my project root.
If I want to run the tests in the tests/large folder for example
How would I go about doing that? Thanks.
For this you could use 2 different approaches:
Create and run test suites.
For example, for each of these folders, create a TestSuite and define Test classes. For example:
#RunWith(Suite.class)
#Suite.SuiteClasses({
ExampleLargeTest.class,
ExampleTwoLargeTest.class,
ExampleThreeLargeTest.class
})
public class LargeTestsSuite {
}
This suite can be run using following command
./gradlew pixel2api30gaeDebugAndroidTest - Pandroid.testInstrumentationRunnerArguments.class=path.to.your.suite.class
Use Test Categories
Annotate your Test classes like this:
#Category("Large")
public class ExampleLargeTest { ... }
And then you could execute the following command for running all tests with same category:
./gradlew pixel2api30gaeDebugAndroidTest -PtestCategory=Large
Hopefully one of these two approaches will suite you.
Android connectedAndroidTest: NO tests found
gradle :aar-lib:connectedAndroidTest
com.android.builder.testing.ConnectedDevice > No tests found.
FAILED No tests found. This usually means that your test classes
are not in the form that your test runner expects (e.g. don't
inherit from TestCase or lack #Test annotations).
Test class:
#RunWith(AndroidJUnit4.class)
public class FooTest {
#Test
public void testFoo() {
....
}
}
Looked at the test APK, it contains the test class.
I just created a new android application with Kotlin Support.
When I've tried to run the default instrumented tests it does not run and shows me this message:
Class not found: "oussaki.com.pos.ExampleInstrumentedTest"Empty test suite.
This the Instrumented test class that I'm trying to run:
#RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
#Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getTargetContext()
assertEquals("oussaki.com.pos", appContext.packageName)
}
}
This is a known issue: https://issuetracker.google.com/issues/38452937 which hopefully will be fixed in the next release.
For the time being you can manually go to 'Edit Configurations' and add the configuration for the specific class/method you want to run under 'Android Instrumented Tests'.
You could also try the latest canary build: https://developer.android.com/studio/preview/index.html but personally I've had trouble getting it to work with my project.
Currently I have a test/src/java folder where all of the tests for the android application are stored (tests are done using junit, mockito and robolectric).
And I can run those using ./gradlew test
What I'd like to achieve is having two folders:
integrationTest/src/java - for integration tests
test/src/java - for unit tests
And also I'd like to run them separately, like ./gradlew test and ./gradlew integrationTest.
I've managed to split directories with tests using sourceSets like this:
sourceSets {
test {
java {
srcDirs = ['src/test/java', 'src/integrationTest/java', 'src/commonTest/java']
}
resources {
srcDirs = ['src/test/resources', 'src/integrationTest/resources', 'src/commonTest/resources']
}
}
}
And I had googled many examples on how to create custom test tasks, but most of them are related to java instead of android and the others are out-of-date. I've spent on that the whole day now and so if someone can help me I would really appreciate that.
If your integration tests are instrumented tests, then you can just use the default folders test and androidTest and run them separately using ./gradlew test and ./gradlew connectedAndroidTest
Another way (if you can have the integration tests inside the test folder) would be to use separate packages inside the test folder and run the tests separately using:
./gradlew testDebug --tests="com.yourapplication.unittests.*"
./gradlew testDebug --tests="com.yourapplication.integrationtests.*"
...
I had the same problem a few days ago.
In order to solve it and be able to run each type of test independently, I separated my tests like this:
// run only unit tests
test{
include '**/unit/**'
exclude '**/integration/**'
doLast {
println 'Unit tests execution finished.'
}
}
// run only integration tests
task integrationTest(type: Test){
include '**/integration/**'
exclude '**/unit/**'
doLast {
println 'Integration tests execution finished.'
}
}
// run all tests (unit + integration)
task allTests(type: Test){
include '**/integration/**'
include '**/unit/**'
doLast {
println 'All tests execution finished.'
}
}
The include keyword indicates which files you want to include when executing the commands. If you want to run only your unit tests, you can only include the folder(s) that include your unit tests and exclude the folders that include your integration tests.
You can use a similar logic when creating a gradle command to run only your integration tests.
To execute your tests using this configuration and gradle, use:
./gradlew test to execute the unit tests only.
./gradlew integrationTests to execute the integration tests only.
./gradlew allTeststo execute both the integration and the unit tests.
NOTE: You can setup the paths in the includes / excludes in order to include / exclude tests or classes when executing your tests. It is also possible to include only one test and exclude the others and vice-versa.
Possibly something like
sourceSets {
integrationTest {
java {
compileClasspath += main.output
runtimeClasspath += main.output
srcDir 'src/integrationTest/java'
}
resources.srcDir 'src/integrationTest/resources'
}
}
configurations {
integrationTestCompile {
extendsFrom compile
}
integrationTestRuntime {
extendsFrom runtime
}
}
task integrationTest(type: Test) {
testClassesDir = sourceSets.integrationTest.output.classesDir
classpath = sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn integrationTest
Then you could do
dependencies {
integrationTestCompile 'org.seleniumhq.selenium:selenium-java:3.0.1'
integrationTestRuntime 'com.foo:bar:1.0'
}
I have Tests set up in an Android project in Android Studio. I have a Unit test class with tests and an Instrumentation test class with tests. When I run gradlew connectedAndroidTest the unit tests run fine but the instrumentation tests are not run.
Here is my project structure
root
- app
- src
- androidTest
- java
- packagename
- UnitTest class
- InstrumentationTest class
The unit test class extends TestCase. The instrumentation test class extends ActivityInstrumentationTestCase2
An example test in the instrumentation test class is
public void testJSONReturnsString() {
String json = JSON.getJSonFeed(getActivity().getApplicationContext(), "http://foo.bar");
assertNotNull(json);
}
In my build.gradle I have
testInstrumentationRunner "android.test.InstrumentationTestRunner"
in the defaultConfig section
Does anyone know why the Instrumentation test class wouldn't run?
In the end it was because I didn't have a default constructor in my instrumentation class!