Flutter coverage reporting in Android Studio [duplicate] - android-studio

I'm developing an open source Android app in Flutter, using Android Studio 3.3.1 (on Window and Ubuntu). The source is available on Github.
The project has a test file that generates coverage data, which can be viewed with tools such as Coveralls. This indicates to me that the LCOV data contains meaningful data.
I want to use inline Code Coverage viewing, similar to the other Jetbrains tools. The run configuration under the 'Flutter Test' category correctly recoginezes my tests, and is able to run them properly.
However, the 'Run with Coverage' option is disabled. I tried different run configurations such as Android JUnit to no avail.
I am aware that I can manually create the coverage data, but my goal is to automate the generation of the coverage data, and showing the coverage inline (just like Coveralls does).
Does anyone know what run configuration, if any, accomplishes this goal?
As a side note, I recently switched to Codemagic as my CI tool so the coverage data on Coveralls is outdated, but the point that the LCOV data is meaningful still holds. I also tried similar setups in Intellij, but the result is the same as Android Studio.

I don't think is supported for Flutter projects yet.
I have all non-UI code in another pure Dart package that I add as dependency to the Flutter project.
For my project this also has the advantage that code that I can share with the browser GUI (Angular Dart) is separated and can't accidentally be polluted with Flutter dependencies that would break the web project.
In this project I can get coverage information in IntellJ when I follow these steps:
You need a "Dart Command Line App" IntelliJ run configuration instead of a "Dart Test", "Flutter" or "Flutter Test" run configuration.
To be able to run tests with a "Dart Command Line App" run configuration you probably need the standalone Dart SDK installed and select it in Preferences > Languages & Frameworks > Dart > Dart SDK path.
To run all tests with coverage instead of individual files you need a file like
test/all.dart
// ignore_for_file: await_only_futures
import 'dart:async';
import 'client/controller/app_controller_test.dart' as i0;
import 'client/controller/authentication_controller_test.dart' as i1;
import 'client/controller/backoffice/backoffice_controller_test.dart' as i2;
import 'client/controller/backoffice/image_reference_controller_test.dart'
as i3;
...
Future<void> main() async {
i0.main();
i1.main();
i2.main();
...
}
with an entry for each test file.
I use a Grinder task like below to generate that file automatically
import 'package:path/path.dart' as path;
...
/// Generate a single Dart file that executes all tests.
/// Dart code coverage reporting still requires that.
#Task('generate test/all.dart')
Future<void> prepareCoverage() async {
final testDir = Directory('test');
final context = path.Context(style: path.Style.posix);
final testFiles = testDir
.listSync(recursive: true, followLinks: false)
.where((e) =>
FileSystemEntity.isFileSync(e.path) && e.path.endsWith('_test.dart'))
.map(
(tf) => context.normalize(path.relative(tf.path, from: testDir.path)))
.toList()
..sort();
final content = StringBuffer('''
// ignore_for_file: await_only_futures
import 'dart:async';
''');
final executions = StringBuffer();
for (var i = 0; i < testFiles.length; i++) {
final testFile = testFiles[i];
content.writeln("import '$testFile' as i$i;");
executions.writeln(' i$i.main();');
}
content
..writeln('Future<void> main() async {')
..writeln()
..writeln(executions)
..writeln('}');
File('test/all.dart').writeAsStringSync(content.toString());
PubApp.global('dart_style')
.run(['-w', '--fix']..add('test/all.dart'), script: 'format');
}

The 'Run with Coverage' option in Android Studio is enabled only for Flutter integration tests for some reason (at least for me).
I wrote an article that describes how to generate code coverage reports locally and on CodeCov and CoverAlls that should get you close to what you want to do. Includes all source code and shows live examples.
It works for both flutter and dart packages.
You can find it here:
https://medium.com/#nocnoc/combined-code-coverage-for-flutter-and-dart-237b9563ecf8

Related

Cannot resolve symbol 'ImmutableList' in Android studio

I try to implement Google Play Pay but don`t know how solve this problem:Type of ImmutableList cannot be resoclved.
Should I import some package?
I have search with Google and no any question like this(Android studio)
ImmutableList.of(QueryProductDetailsParams.Product.newBuilder()
.setProductId("product_id_example")
.setProductType(BillingClient.ProductType.SUBS)
.build())
Android Studio suggests the firebase-crashlytics-buildtools dependency to import the ImmutableList class. Doing so resulted in a big increase of the file (bundle) size.
Try instead including guava as a dependency, if you are not using crashlythics in your app:
// graddle
implementation 'com.google.guava:guava:31.1-android'
// java class/code
import com.google.common.collect.ImmutableList;
This has a much smaller impact on the file size. In my case, the bundle was 2MB compared to 10 MB if using crashlythics-buildtools.
I run into the same problem. By hovering with the pointer over 'ImmutableList' I selected the entry Add dependency on com.google.firebase:firebase-crashlitics-builtools and import...
This action created the following line in the import section of my activity file
import com.google.firebase.crashlytics.buildtools.reloc.com.google.common.collect.ImmutableList;
and the following line in the build.gradle file:
implementation 'com.google.firebase:firebase-crashlytics-buildtools:2.7.1'
However, the word reloc in the import line initially appeared in red color with the hint Cannot resolve symbol 'reloc'. Then I noticed that in the build.gradle file, android studio was offering to change the version of the crashlytics-buildtools from 2.7.1 to 2.9.1. After doing so and syncing gradle, the word reloc was no longer red and ImmutableList was recognized correctly.
I wonder whether it is really necessary to import the firebase crashlytics-buildtools for the integration of the Google Billing Library (I use it for an app with in-app purchases) or if there is a more simple way to do this.

Updated android studio and got fail with Gstreamer build

Updated to Android Studio 3.0.0 with new android gradle plugin.
While buildin project got message:
What went wrong:
Execution failed for task `':app:externalNativeBuildDebug'`.
Expected output file at `gst-build-arm64-v8a/libgstreamer_android.so` for target `gstreamer_android` but there was none
but libgstreamer_android.so library file is already there. For native code I use ndk-build. Does anyone have this issue?
Add to build.gradle file of our android module field targets.
android {
defaultConfig {
externalNativeBuild {
ndkBuild {
targets "name_of_native_module_in_android_mk_file"
}
...
}
Don't add gstreamer_android.
UPDATE: Valery's answer works!
Obsolete answer:
That's not the perfect fix, it's just temporary until I have time to take a deep look into the problem. Downgrade your gradle plugin:
File -> Project Structure
Click at "Project"
At "Gradle version" field put:
3.3
At "Android Plugin Version" field put:
2.3.3
Hit "OK"
Accept the messages, sync the project, etc... Android Studio may prompt a windown asking for update gradle plugin again, just don't accept it for now...
I guess the update on gradle changed the way the builds are made, maybe something on Android.mk will have to change or some other parameter on build.grade...
edit: I found some clue at: https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html
API changes Android plugin 3.0.0 introduces API changes that removes
certain functionalities and may break your existing builds. Later
versions of the plugin may introduce new public APIs that replace
broken functionalities.
Modifying variant outputs at build time may not work Using the Variant
API to manipulate variant outputs is broken with the new plugin. It
still works for simple tasks, such as changing the APK name during
build time, as shown below:...
So, I guess we should keep using the temporary fix (not updated version of gradle)...

Deploying multiple build variants at a time - Android studio gradle

I recently discovered this awesome feature about gradle productFlavors. I currently have 3 variants (staging, sandbox and production) and I can deploy one of the variants at a time using build variant panel.
Is there a way I can deploy all variants at a time?
Yes,
In Android Studio, open the "Gradle Tasks" tab, which is usually on the right. You will see many tasks that start with 'assemble', double click on one of those.
For example, double clicking on 'assembleRelease' will create all your release apks.
From the docs:
Building and Tasks
We previously saw that each Build Type creates its own assemble
task, but that Build Variants are a combination of Build Type and
Product Flavor.
When Product Flavors are used, more assemble-type tasks are created.
These are:
1) assemble[Variant Name]
2) assemble[Build Type Name]
3) assemble[Product Flavor Name]
1) allows directly building a single variant. For instance
assembleFlavor1Debug.
2) allows building all APKs for a given Build Type. For instance
assembleDebug will build both Flavor1Debug and Flavor2Debug variants.
3) allows building all APKs for a given flavor. For instance
assembleFlavor1 will build both Flavor1Debug and Flavor1Release
variants.
The task assemble will build all possible variants.
If you know the names of the gradle tasks that install your variants you can run this from the root of your project in the terminal:
./gradlew install{VariantName1, VariantName2, VariantName3}Debug
This assumes you have a module build.gradle file with variants set up according to the guide. So something along these lines:
apply plugin: 'com.android.application'
android {
...
flavorDimensions "myFlavorDimension"
productFlavors {
VariantName1 {
...
}
VariantName2 {
...
}
VariantName3 {
...
}
}
...
}
dependencies {
...
}
You can find these gradle task names either in Android Studio in the Gradle Tab (right side of GUI) under you moduleName->Tasks->install
Or you can find them in the terminal with:
./gradlew tasks | grep install
I'm sure there is some Regex that could grab only the ones of interest programmatically as well, but I'm not a regex buff. If you want to leave a comment with something that would work, I'd be happy to edit and add later.

FlashDevelop/OpenFL: How to set default target to neko

I am trying to write some cross-language code with Haxe/OpenFL and compile it using FalshDevelop. But I get an error as soon as I use the basic Sys.print function. A minimal example is as follows:
package;
import flash.display.Sprite;
class Graphic extends Sprite {
public function new () {
super ();
}
static function main() { //used in standalone swf project
Sys.print("Hi");
}
}
It turns out that the default compile command of FlashDevelop is something like:
haxelib run openfl build project.xml flash
,which gives an error on Sys.print:
Graphic.hx:xx: characters 2-11 : Accessing this field requires a system platform
(php,neko,cpp,etc.)
My guess is that Sys.print isn't available in the flash target or flash isn't a system platform (strange). I was wondering if there is way to work around this, and configure FlashDevelop so that the compile command is:
haxelib run openfl build project.xml neko
Thanks
There are actually 2 questions.
For the first one, Sys.print is available only on some platforms because it wouldn't make sense in others(what would it do in flash?), what you probably want is trace, which is used to print things for debug purposes.
For the second question there is a drop down menu at the top of flashdevelop if you created a openfl project that looks like this and does exactly that:

Cucumber/gradle example not generating report?

I'm investigating using gradle and cucumber together, and found this lovely example in cucumber's github.
So, I cloned the repository and ran it myself. It failed, as it's configured to do, but I couldn't find the HTML or JSON report that it appears to be configured to output. I say appear because I'm brand new to cucumber, but this class would seem to indicate where it'll put it:
#RunWith(Cucumber.class)
#Cucumber.Options(format = {"pretty", "html:build/cucumber-html-report", "json-pretty:build/cucumber-report.json"})
public class RunCukesTest {
}
However, it's not appearing in the build directory after running gradle cucumber.There's no cucumber-html-report directory, not is there a cucumber-report.json file. I'm running it with Java 7 and Gradle 1.6, if it matters.
Ideas? Is this a known issue with the Cucumber/Gradle integration?
The class name changed depending on the version of Cucumber you are using. It changed from json-pretty to json.
When running the 'cucumber' task on this example the generated cucumber report is located at 'build/cucumber-html-report/index.html'. Running the 'test' task fails as it seems that gradle has problems to create the test report for the cucumber created tests (file name contains spaces) I need to dig a bit into this to see how this can be fixed in gradle.
cheers,
René
The cucumber-jvm-example doesn't do reporting using gradle cucumber, but does do it with gradle test. However, gradle test will have a couple issues, namely showing a "null" test of sorts.
A workaround to this, if need be, is to add the formats to the args of the javaexec that runs cucumber. For example, in build.gradle:
javaexec {
main = "cucumber.api.cli.Main"
classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
args = ['--format', 'html:cucumber-html-report', '-f', 'pretty', '--glue', 'gradle.cucumber', 'src/test/resources']
}
I had an error with that very same line (taken from this tutorial).
In order to resolve, had to change the third parameter from "json-pretty" to just "pretty"
So this is my final code line:
#CucumberOptions(format = {"pretty", "html:target/cucumber-html-report", "pretty:target/cucumber-report.json"})
BTW,
#Cucumber.Options is deprecated, we should use CucumberOptions

Resources