How to retrigger multiplatform tests? - android

I wrote a multiplatform test class in Kotlin of form:
class GreetingTest : BaseTest() {
companion object {
private var retriggerCounter: Int = 0
}
#Test
fun testRetrigger() {
assertTrue(retriggerCounter++ >= 3)
}
}
This class is supposed to be failing twice and passing the third time (I want to test tests retriggers, to this static counter is used to fail assertTrue twice and pass the test on the third try).
I run the test using xcodebuild test -project iosApp.xcodeproj -scheme iosAppUITests -destination ‘platform=iOS Simulator,name=iPhone 13,OS=14.1’ -resultBundlePath TestResults -retry-tests-on-failure. Please note the -retry-tests-on-failure option, it's used to automatically retry tests upon failure (up to 3 times as default).
I run this test from iOS native side and the problem is, that when the test fails for the first time, I get an error: Function doesn't have or inherit #Throws annotation and thus exception isn't propagated from Kotlin to Objective-C/Swift as NSError. It is considered unexpected and unhandled instead. Program will be terminated.
So generally the issue is that Kotlin returns an AssertionError and since Swift does not know what that is, it is unexpected/unhandled and the program is terminated, thus the tests are NOT being retriggered.
I idea to overcome this was to add #Throws(AssertionError::class) like so:
class GreetingTest : BaseTest() {
companion object {
private var retriggerCounter: Int = 0
}
#Test
#Throws(AssertionError::class)
fun testRetrigger() {
assertTrue(retriggerCounter++ >= 3)
}
}
but this way it does not work as well, because the tests are passing! Apparently Swift getting AssertionError somehow translates it to a passed test case and does not retrigger the test (because it did not fail).
What should I do? Should I somehow catch the error on the iOS side or maybe change the structure in Android?
Any help would be appreciated!

Related

Test classes doesn't work correctly on android?

I'm a newbie in unit testing in android and I follow this repository on implementing it but when I done it and run it my test it passes always even if I make a different clear assertion
like that
MatcherAssert.assertThat(25, CoreMatchers.`is`(20))
so I thought I made something wrong and I tried to clone the repository and try it and found the repository also passed in all cases , I tried to change the MainCoroutineRule from this to this and now the tests work but not passed
for example in Repository test it gives me this error
junit.framework.AssertionFailedError:
Expected :com.fevziomurtekin.deezer.core.data.ApiResult$Loading#5c7933ad
Actual :Success(data=[AlbumData(diskNumber=1, duration=320, explicitContentCover=0, explicitContentLyrics=0,.......
and the method for that test case
#ExperimentalTime
#Test
fun fetchAlbumTracksFromNetworkTest() = runBlocking {
val mockData = AlbumDetailsResponse(data = listOf(MockUtil.album), total = 12)
val returnData = Response.success(mockData)
whenever(service.fetchAlbumDetails(MockUtil.albumID)).thenReturn(returnData)
repository.fetchAlbumTracks(MockUtil.albumID).test {
val result = expectItem()
assertEquals(result, ApiResult.Success(listOf(MockUtil.album)))
Assert.assertEquals((result as ApiResult.Success<List<AlbumData>>).data[0].title, "Alo")
Assert.assertEquals(result.data[0].id, "425605922")
Assert.assertEquals(result.data[1].title, "Geceler")
Assert.assertEquals(result.data[1].id, "425605932")
expectComplete()
}
verify(service, atLeastOnce()).fetchAlbumDetails(MockUtil.albumID)
verifyNoMoreInteractions(service)
}
and for Viewmodel it gives me this error
Argument(s) are different! Wanted:
observer.onChanged(
Success(data=[ArtistAlbumData(cover=https://api.deezer.com/album/51174732/image, cov
for this test case
#Test
fun fetchAlbumListTest() = runBlocking {
val mockList = listOf(MockUtil.album)
val observer : Observer<ApiResult<List<AlbumData>>> = mock()
val fetchedData : LiveData<ApiResult<List<AlbumData>>> = repository.fetchAlbumTracks("302127").asLiveData()
fetchedData.observeForever(observer)
viewModel.fetchingAlbumDatas(MockUtil.albumID)
delay(500L)
verify(observer).onChanged(ApiResult.Success(mockList))
fetchedData.removeObserver(observer)
}
and for Api test here it also fails to read input stream from input json files
Did I setup anything wrong on test configuration which makes the tests fails or the tests itself is wrong,the weird is the repository which I used there are many test classes for the whole project and I wonder if it didn't work it won't be pushed!
update: I open an issue on the repository and it has more details of what happens here
hope anyone can help with that?

Unresolved reference for BR.propertyName when calling notifyPropertyChanged, app builds and runs fine

I'm using Android Studio 3.5, Kotlin, and databinding. I have a property setup for 2 way databinding:
var startValue: String
#Bindable get() {
return when(mode)
{
PullingModes.SOTrackingPaintShop->if(salesOrderInformation.zoeordh!!.psstart == null) "" else salesOrderInformation.zoeordh!!.psstart!!
else->""
}
}
set(value: String) {
if(mode == PullingModes.SOTrackingPaintShop && salesOrderInformation.zoeordh!!.psstart != value)
salesOrderInformation.zoeordh.psstart = value
notifyPropertyChanged(BR.startValue)
}
In the last line, I get a design time error of Unresolved Reference: startValue
The BR class is properly generated, and startValue exists in the generated BR class. The project builds and runs fine. I've tried all the common things to try to fix this--clean and rebuild, along with Invalidate caches and restart and still can't get the design time error to go away. I experience the same issue with the Google sample 2 way databinding project: https://github.com/googlesamples/android-databinding
Anyone else experience this and have a resolution for it?

Is it possible to use custom java class to throw an exception in Crashlytics with Nativescript Android?

I'm trying to return my Javascript exceptions in Crashlytics. It works but it all appears under the problem :
Runtime.java com.tns.Runtime.callJSMethodNative
in the Crashlytics dashboard. I'd rather see my problem list like this :
MyScreen1.ts org.mycompany.monapp.myScreen1
MyScreen2.ts org.mycompany.monapp.myScreen2
I know that Crashlytics is not made to handle JavaScript errors but I would like to simulate this behavior as closely as possible. I tried to log my exception form a custom java class like this :
#JavaProxy("org.demonativescript.MyErrorHandler")
export class MyErrorHandler extends java.lang.Object {
constructor() {
super();
return global.__native(this);
}
sendCrash() : void{
crashlytics.sendCrashLog(new MyCustomException("My Custom Excep"));
}
};
But since the exception is still logged from the JavaScript runtil, the problem appears under :
Runtime.java com.tns.Runtime.callJSMethodNative

Google Espresso: delete user data on each test

I'm looking for a way to delete the database from the app before each test using Google Espresso.
I've got this piece of code in a #Before function (kotlin code):
#Before
fun setUp() {
val appCtx = InstrumentationRegistry.getTargetContext().applicationContext
DBPrefsManager.getInstance(appCtx).resetAll()
val client = appCtx.contentResolver.acquireContentProviderClient("fr.geobert.radis.db")
val provider = client.localContentProvider as DbContentProvider
provider.deleteDatabase(appCtx)
client.release()
val i = Intent()
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
activityRule.launchActivity(i)
}
It used to work before but I left my part time project for some month and now, after upgrading to API 23 and new testing framework version, all my test can't start because of the "activityRule.launchActivity(i)". So I got rid of the last 3 lines and the tests can start again but by delete database code fails one time in two :(
Is there any better way to delete user data before the app is started by the test framework?

Scala on Android with scala.concurrent.Future do not report exception on system err/out

We build an android application with Scala 2.11. We use scala.concurrent.Future for async background tasks. The problem is, that we do not see any exceptions in logcat if exceptions are thrown inside a Future block.
We already create an execution context with our own reporter:
lazy val reporter: (Throwable => Unit) = {
t =>
t.printStackTrace()
}
implicit lazy val exec = ExecutionContext.fromExecutor(
new ThreadPoolExecutor(10, 100, 5, TimeUnit.MINUTES,
new LinkedBlockingQueue[Runnable]), reporter)
Even if I set a breakpoint inside the reporter the debugger does never stop here, even if I force throwing of exceptions insde a Future {...} block.
What are we doing wrong
According to your comment it looks like you simply didn't work with Future as needed. When some exception occurred during the Future computation it is transformed into Failure case (like Failure from Try, but in async context), e.g:
scala> Future { 10 / 0 }
res21: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise#24f3ffd
As you can see there is no exception thrown or printed. To handle this exception you need to use callbacks, i.e onComplete or onFailure, e.g:
scala> res21.onFailure { case error => println(s"Error: ${ error.getMessage }") }
Error: / by zero
A great intro into Futures and Duality was given by the man with psychedelic T-Shirt Erik Meijer in the coursers intro to Reactive Programming.

Categories

Resources