In Android Studio I created androidTest package and added a TestClass.
The #BeforeClass function is required to be static,
so I have to add #JvmStatic and put it in the companion object.
But if put assertNotNull() inside the companion object it will show “Empty test suite” when running the test, and the test does not run.
But it does see the "+++ +++ initBeforeTest()" log which is placed before the assertXXX statement.
+++ +++ initBeforeTest()
++ +++ afterTest()
Client not ready yet..
Started running tests
Tests ran to completion.
Empty test suite.
If I comment out the assertNotNull() in the #BeforeClass function, which is inside the companion, the test will run as expected.
+++ +++ initBeforeTest()
++ +++ afterTest()
Client not ready yet..
Started running tests
java.lang.AssertionError: test assertNotNull
at org.junit.Assert.fail(Assert.java:88)
Any idea why the assertNotNull() (actually all assertXXX functions) causes the test not to run?
Gradle has:
testImplementation "junit:junit:4.12”
androidTestImplementation "com.android.support.test:runner:1.0.1”
test class:
#RunWith(AndroidJUnit4::class)
class TestClass {
companion object {
#BeforeClass #JvmStatic
fun beforeTest() {
Log.e("+++","+++ +++ initBeforeTest()")
// if comment out this assertNotNull(), the test will run
assertNotNull("test assertNotNull", null) //<== causes "Empty test suite."
}
#AfterClass #JvmStatic
fun afterTest() {
}
}
#Test
fun test1() {
assertNotNull("test assertNotNull", null)
}
}
Keep in mind that if the method you've annotated with #BeforeClass fails, the Junit Runner will not execute the rest of the suite.
Because your assertion (assertNotNull("test assertNotNull", null)) fails, an exception is thrown (actually an AssertionError) causing the suite setup to fail. This in turn causes the test runner to assume it has no tests. That's why removing the failing assertion will cause the tests to run (because the setup succeeds).
If you change your assertion in the setup to this, I suspect it will pass:
assertNull("test assertNull", null)
Edit: To be more clear, when you use assertNotNull you are telling Junit that the value provided cannot be null, and in your case it is. The first argument to assertNotNull ("test assertNotNull") is a message that will be incorporated into the failure message (as you can see in the output you've provided). The second argument (null, in this case) is the thing that cannot be null.
Related
I been trying to run a unite test and I am now facing some issue in mocking the Application Context. I tried mockStatic() but is not working. I am using Junit 5 and org.mockito:mockito-inline:3.4.6 for testing.
class ApplicationContext : Application() {
init {
instance = this
}
companion object {
private var instance : ApplicationContext? = null
fun applicationContext() : Context = instance!!.applicationContext
}
When I run my test this throws a NullPointerException.
java.lang.NullPointerException
at com.adaptavant.yoco.Util.ApplicationContext$Companion.applicationContext(ApplicationContext.kt:14)
at com.adaptavant.yoco.viewModel.LoginViewModelTest.setUp(LoginViewModelTest.kt:48)
Can Someone help me out here.
There is no ApplicationContext available in unit test - you need to use instrumentation tests for that:
Local unit tests:
Use these tests to minimize execution time when your tests have no Android framework dependencies or when you can mock the Android framework dependencies.
Instrumented tests
These tests have access to Instrumentation APIs, give you access to information such as the Context of the app you are testing, and let you control the app under test from your test code.
Source
In iOS there exists a tear block you can add to individual tests called addTearDownBlock and you put it inside a single test and it will only execute for that single test.
Does android have a similar version of this?
Unit testing in android is done with xUnit variation known as JUnit. If you are using JUnit 4.0, then use the following annotation:
#AfterClass //Will only execute once after all the tests in the class have exhausted
#After //Will run after every test
If you are using JUnit 5.0 then use the following annotation:
#AfterEach //Will run after every test
#AfterAll //Will only execute once after all the tests in the class have exhausted
I have written multiple test methods in a single android instrumented test class, when I am trying to run a single test method it will run all methods exists in that class.
I want to run only one.
Earlier I was able to run all, but somehow configuration settings have been changed
class HistoryTest{
#Test
fun openHistoryTest{
}
#Test
fun closeHistoryTest{
}
#Test
fun editHistoryTest{
}
}
I want to run a specific single test method say openHistoryTest.
Currently getting an error - the command line is too long shorten the command line for test "testname"
I updated Android Studio to canary and can run the whole class or a single method as instrumental test. Currently using AS 3.6 Canary 12.
Still doesn't work on Android Studio 3.5. I can't run each method as an
instrumental test, only the whole class.
I want to do some test of coroutines in JUnit but I met some problems. Code is easy:
#Test
fun coroutineTest() {
//runBlocking(Unconfined) doesnt work too
runBlocking () {
delay(1000)
println("test")
}
}
But I got that error
java.lang.RuntimeException: Method myLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.
at android.os.Looper.myLooper(Looper.java)
at kotlinx.coroutines.experimental.android.MainLooperChecker.checkRunBlocking(HandlerContext.kt:124)
at kotlinx.coroutines.experimental.BuildersKt__BuildersKt.runBlocking(Builders.kt:42)
at kotlinx.coroutines.experimental.BuildersKt.runBlocking(Unknown Source)
at app.deadmc.sometests.tests.ExampleUnitTest.coroutineTest(ExampleUnitTest.kt:22)
The first thing I thought about was wrong coroutine context. So to be sure I used Unconfined but that doesnt work.
I`ve tried
android {
// ...
testOptions {
unitTests.returnDefaultValues = true
}
}
But that doesn`t work too and I get following error:
java.lang.IllegalStateException: runBlocking is not allowed in Android main looper thread
But there is no Android main looper at all!
How can I run blocking coroutine in JUnit?
Thanks Marko Topolnik for idea.
The problem is with 0.24.0 version of coroutines because of:
Attempts to use runBlocking from any supported UI thread (Android,
JavaFx, Swing) will result in exception.
Unfortunately release has a bug with JUnit tests, so it doesnt let to use runBlocking in JUnit aswell.
Solution is changing version of coroutines to 0.23.4
You can remove this check via an environment variable.
Either set it in your tests initilization:
System.setProperty("kotlinx.coroutines.blocking.checker", "disable")
Either set the env variable via Gradle with:
-Dkotlinx.coroutines.blocking.checker=disable
This simple test
#RunWith(JUnit4::class)
class Test {
#Test
fun test() {
assert(false)
}
}
Unexpectedly, this passes when put in androidTest (both through Android Studio and in the terminal), but obviously fails as expected when put in test.
You need to use JUnit assertions for running tests. The base assert() functionality is normally disabled when running "production" code, so you cannot depend that a plain assert statement will throw an assertion exception.
Use:
org.junit.Asserts.assertTrue( false )
to make the test fail properly.