Is R8 / Android Gradle Plugin smart enough to keep library classes/methods needed only in test apk? - android-gradle-plugin

Let's say I have an app that depends on a library. This library has two methods:
void usedInApp()
void usedInTest()
In the app I call usedInApp(). I also have an instrumentation test that calls usedInTest(). If I run instrumentation tests ./gradlew app:connectedDebugAndroidTest is R8/AGP smart enough to know to keep usedInTest() or will it get removed?

As usedInTest is not used by the app R8 will remove it, and when running your test it will fail with a MethodNotFouldError. So you need a keep rule to make sure usedInTest is still in the app when testing. One good way to do that is to add an annotation, e.g. KeepForTesting and annotate in the app what the tests need. And then add this keep rule:
-keep,allowobfuscation class * {
#KeepForTesting *;
}
Note the allowobfuscation modifter. That allows these methods for testing to be renamed to shorter names. When Android Studio builds the tests it will automatically add an -applymapping option with the mapping file produced when building the app. This way the reference to usedInTest in the tests will be renamed to the actual method in the app after running R8.
For R8 itself we have automated that by analyzing the R8 tests to find what parts of R8, which are not on the public API, are used in the tests. From that we synthesize keep rules to keep this. Then we can run R8 on R8, and then run all tests on that version of R8 - which is also the version we ultimately ship.

Related

Karate summary reports not showing all tested features after upgrade to 1.0.0

I have recently upgraded to version 1.0.0 from 0.9.6 and noticed that the generated karate-summary.html file, it doesn't display all the tested feature files in the JUnit 5 Runner unlike in 0.9.6.
What it displays instead was the last tested feature file only.
The below screenshots are from the provided SampleTest.java sample code (excluding other Tests for simplicity).
package karate;
import com.intuit.karate.junit5.Karate;
class SampleTest {
#Karate.Test
Karate testSample() {
return Karate.run("sample").relativeTo(getClass());
}
#Karate.Test
Karate testTags() {
return Karate.run("tags").relativeTo(getClass());
}
}
This is from Version 0.9.6.
And this one is from Version 1.0.0
However, when running the test below in 1.0.0, all the features are displayed in the summary correctly.
#Karate.Test
Karate testAll() {
return Karate.run().relativeTo(getClass());
}
Would anyone be kind to confirm if they are getting the similar result? It would be very much appreciated.
What it displays instead was the last tested feature file only.
This is because for each time you run a JUnit method, the reports directory is backed up by default. Look for other directories called target/karate-reports-<timestamp> and you may find your reports there. So maybe what is happening is that you have multiple JUnit tests that are all running, so you see this behavior. You may be able to over-ride this behavior by calling the method: .backupReportDir(false) on the builder. But I think it may not still work - because the JUnit runner has changed a little bit. It is designed to run one method at a time, when you are in local / dev-mode.
So the JUnit runner is just a convenience. You should use the Runner class / builder for CI execution, and when you want to run multiple tests and see them in one report: https://stackoverflow.com/a/65578167/143475
Here is an example: ExamplesTest.java
But in case there is a bug in the JUnit runner (which is quite possible) please follow the process and help the project developers replicate and then fix the issue to release as soon as possible.

`vectorResource` throws RuntimeException when ProGuard applies optimizations

I am using Jetpack Compose 1.0.0-alpha09 with Kotlin 1.4.21. I use vectorResource to load an ImageVector from resources.
All works fine in the design previews and for debug builds. However, when I build a release build with ProGuard, I get the following exception at runtime:
org.xmlpull.v1.XmlPullParserException: Binary XML file line #1<VectorGraphic> tag requires viewportWidth > 0
at androidx.compose.ui.autofill.AndroidAutofillDebugUtilsKt.vectorResource(AndroidAutofillDebugUtils.kt:142)
at ...
After a long tedious process trying to identify differences between release and debug which may cause this, I have discovered that disabling optimization in ProGuard using -dontoptimize 'solves' this issue.
What exactly causes this discrepancy in behavior? Is this a bug in, Jetpack Compose, ProGuard, or in my configuration of ProGuard?

Integration tests in golang - how to test the link between the router and the http.Handlers?

I've been tinkering around with golang and I try to implement a little todo application which should grow with the time. My thoughts about the applications architecture are the following:
The main package sets up the server and integrates the "services/handler" of the other packages in it's router under the corresponding path prefixes.
Every "service" has its own handlers and routes them correctly
So I've started just with the main package and wrote some todo handlers. To test the API I've written some integration tests (request/response). Now, I've removed the todo logic from the main package into it's own. When I execute go test -cover it shows me just the coverage of the main.go, but not for the todo package. That leads me to the conclusion that each package has to test on it's own.
So I have not to test the API in the main package but the integration, that '/todos' ends up in the todo package and nothing more, is that right? How can I test that? And in the todo package I have to test:
The routing in the package
And with a response recorder the API implementation
Is that right too? So how can I test the routing on it's own? Is that possible?
Here is my git repository:
https://github.com/fvosberg/mrsjenkins
Thanks in advance

Ember.js testing component with service dependency

I'm trying to write tests for my addon, but encountering some weird behaviour.
I have created a service (via ember-cli generate), which is used inside a component.
When an actual application is running everything is working fine.
However, when testing the component I get an error saying that the service is undefined when trying to access any of its properties/methods.
In the test i've put the service in "needs" like so:
needs: ['service:my-service']
"Needing" other components (e.g. child ones used inside) works as expected, services strangely fail.
Are there any additional steps that need to be done?
Running ember-cli 0.1.12.
When you generate a service, it also generates an initializer whose job it is to inject the service into the various places that you need it.
So, when you run acceptance tests your app will have booted and initializers will have been run, therefore the services will be available.
However, when unit testing components you get a clean container (better for testing). You just need to inject what you need:
moduleForComponent('foo-bar', null, {
setup: function(container) {
container.register('service:foo', FooService);
container.injection('component', 'fooService', 'service:foo');
}
});
I managed to get this working by using the new Ember.inject API available in the latest (as of writing) 1.10 release.
Apparently the new inject API is intended to replace needs in the future, it also works great with unit tests.
We just managed to get one working using needs: ['service:myService'] instead of needs: ['service:my-service'].

Yii CAssetManager.basePath is invalid on PHPUnit test

i have a problem to run test. My model use extension Yii mail and then i run test its fail with wrong assert path. Another test runs finaly (model dont use any extensions). Preloading is only log.
I had a similar error and I explicitly set the basePath in config/test.php.
'components'=>array(
...
'assetManager'=>array(
'basePath'=>dirname(__FILE__).'/../../assets',
)
)
Im solved problem
public function setUp(){
Yii::app()->assetManager->basePath = '../../asserts';
}
Im dont know why this error throw only in one model...
PhpUnit runs primary in CLI mode and therefore some of environmental variables are missing. Yii's AssetManager uses one of such variable to determine webroot and since the variable does not exist, it will either throw error or set up invalid assets path on first attempt.
In my opinion, this issue is (indirectly) caused by PHPUnit because it only supports CLI testing mode, which makes some things really more difficult to test than it would be in HTTP request mode. Some guys therefore wrote tools to run unit tests via standard web GUI with whole native HTTP environment (e.g. https://github.com/NSinopoli/VisualPHPUnit). Eventually, you may use HTTP clients like Selenium to run your tests as if clicking over the page (see http://phpunit.de/manual/3.7/en/selenium.html).
Nevertheless, it's a matter of subjective opinion - somebody may argue, that testing in CLI mode has advantages, some guys will hate it. But the fact is, that one has to bear in mind differences between HTTP and CLI mode.