I am using ActiveAndroid for some of my models, and I wanted to start unit testing my work. Unfortunately, I am getting a load of errors, namely in being unable to initialize ActiveAndroid using the proper context.
ActiveAndroid is iniatilized:
ActiveAndroid.initialize(context)
I have tried to initialize a context by:
Have a stub class that extends Application, and use that to initialize db.
private class TestApp extends com.activeandroid.app.Application{
#Override
public void onCreate() {
super.onCreate();
initialiseDB(getDatabaseName());
}
protected String getDatabaseName() {
return "sad";
}
private void initialiseDB(String dbName) {
ActiveAndroid.initialize(this);
}
}
This fails, as the class return null for .getPackageName() and .getApplicationContext(), both of which are used internally by the initialize.
I have also tried using ShadowContextWrapper, but I may be using it wrong. Here is how I went about it:
ShadowContextWrapper shadowContextWrapper = new ShadowContextWrapper();
shadowContextWrapper.setApplicationName("appName");
shadowContextWrapper.setPackageName("package");
Context context = shadowContextWrapper.getApplicationContext();
This approach fails with an NPE at ShadowContextWrapper.java:52
which part of Robolectric. The line itself:
Context applicationContext = this.realContextWrapper.getBaseContext().getApplicationContext();
I am using AS 1.2, robolectric3.0 and activeandroid 3.1.
Here is an example of a Test I am running.
#RunWith(CustomRobolectricTestRunner.class)
public class ItemTest {
public void setUp(){
}
#Test
public void checkJUnitWork() {
assertThat(true, is(true));
}
#Test
public void testSave(){
Item item = new Item("name", "units", 5.0, 4.5, 10.0);
assertThat(item.getName(),is("name"));
}
public void tearDown(){
}
}
My custom Runner is as follows:
public class CustomRobolectricTestRunner extends RobolectricTestRunner {
public CustomRobolectricTestRunner(Class<?> testClass)
throws InitializationError {
super(testClass);
String buildVariant = (BuildConfig.FLAVOR.isEmpty()
? "" : BuildConfig.FLAVOR+ "/") + BuildConfig.BUILD_TYPE;
String intermediatesPath = BuildConfig.class.getResource("")
.toString().replace("file:", "");
intermediatesPath = intermediatesPath
.substring(0, intermediatesPath.indexOf("/classes"));
System.setProperty("android.package",
BuildConfig.APPLICATION_ID);
System.setProperty("android.manifest",
intermediatesPath + "/manifests/full/"
+ buildVariant + "/AndroidManifest.xml");
System.setProperty("android.resources",
intermediatesPath + "/res/" + buildVariant);
System.setProperty("android.assets",
intermediatesPath + "/assets/" + buildVariant);
ShadowContextWrapper shadowContextWrapper = new ShadowContextWrapper();
shadowContextWrapper.setApplicationName("appName");
shadowContextWrapper.setPackageName("package");
Context context = shadowContextWrapper.getApplicationContext();
ActiveAndroid.initialize(context);
}
}
So, the issue you're having with your tests is that TestApp is not running. To get it running, you need to setup your test to use a manifest that specifies TestApp as the application to run.
Setup your TestApp as follows somewhere in /test directory of your source tree... e.g. /src/test/java/some-long-package/TestApp.java:
package com.some.company;
public class TestApp extends Application {
#Override
public void onCreate() {
super.onCreate();
ActiveAndroid.initialize(this);
}
}
This is the important part
Create an android manifest file in the /test tree of your source. Have this manifest file specify the TestApp as the application. So, create a manifest at a path like /src/test/resources/TestManifest.xml containing the following:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.test">
<application android:name="com.some.company.TestApp">
</application>
</manifest>
I'd recommend getting rid of the CustomRobolectricTestRunner as the default Robolectric 3.0 test runner will do most of what you need done. If you need to test various build variants, use #RunWith(RobolectricGradleTestRunner.class).
But for now, setup your tests as follows:
#RunWith(RobolectricTestRunner.class)
#Config(constants = BuildConfig.class, manifest = "src/test/resources/TestManifest.xml", sdk = Build.VERSION_CODES.LOLLIPOP)
public class MainAppTest {
#Test
public void runtimeApplicationShouldBeTestApp() throws Exception {
String actualName = RuntimeEnvironment.application.getClass().getName();
String expectedName = TestApp.class.getName();
assert(actualName).equals(expectedName);
}
}
That #Config(manifest= ...) bit will setup Robolectric to use the test manifest and the test application. The test above simple validates that the application context being used within the test is indeed the TestApp.class
This will ensure ActiveAndroid is initialized correctly for the test.
I also agree with Eugen that you may be trying to do a little bit much in your tests. By testing your DB through your application, you are effectively creating an integration test. I'd recommend splitting out the functionality as much as possible.
Happy testing!
Related
I've started learning android unit tests, but it looks very hard to find some good guides or information. Every example have a stupid example about 2+2 = 4
Say I write a little SDK which has few functions
MySdk.Init(Context context)
MySdk.CallTask()
I create an androidTest file
How should I call my SDK functions to check how they work? Somewhere required parameters like int/string/context. I just really don't understand, please help me.
This is what I've tried
public class AndroidTest {
private Activity context;
//default test
#Test
public void addition_correct() throws Exception {
assertEquals(4, 2 + 2);
}
#Test
public void checkContext() {
context = getActivity();
assertNotNull(context);
}
#Test
public void testInitPhase() {
MySdk.Init(context, new SdkInitializationListener() {
#Override
public void onInitializationSuccessful(String adv_id) {
assert (adv_id != null);
}
#Override
public void onInitializationError() {
}
});
}
}
For context i was tried context = new mockContext();. It's passed as context = null and my SDK failed with initialization.
Unit tests are mainly about testing an individual class in isolation, so that you can check if individual public methods of a class behave as you intend them to, and continue to do so if you change that class' code in the future. Let's say you have a class like this:
public class UtilityFunctions {
public int double(int value) {
return value * 2;
}
public String mirror(String value) {
if (value == null) return "";
return value + new StringBuilder(value).reverse().toString();
}
}
You want to test these two methods with:
valid input values, and check the output is as expected
invalid values, and check that errors are handled accordingly (and the correct exceptions thrown if necessary)
So a test class for the above class may look like this
#RunWith(JUnit4.class)
public class UtilityFunctionsTest {
private UtilityFunctions utility;
#Before
public void setUp() {
// Initialises any conditions before each test
utility = new UtilityFunctions();
}
#Test
public void testDoubleFunction() {
assertEquals(2, utility.double(1));
assertEquals(8, utility.double(4));
assertEquals(-12, utility.double(-6));
assertEquals(0, utility.double(0));
}
#Test
public void testMirror() {
assertEquals("", utility.mirror(null));
assertEquals("", utility.mirror(""));
assertEquals("aa", utility.mirror("a"));
assertEquals("MirrorrorriM", utility.mirror("Mirror"));
}
}
These standard Java unit tests are run from the test directory. However, you'll need to run tests in the androidTest directory whenever you're using Android-specific classes such as Context. If you're creating a MockContext, you're simply creating an empty Context whose methods don't do anything.
Without me knowing anything about what your MySDK does, I think you may need to pass a fully-functioning Context into your class for your tests. The Android JUnit runner does provide this with InstrumentationRegistry.getTargetContext(), so for your example, you may need to add this #Before method:
#Before
public void setUp() {
context = InstrumentationRegistry.getTargetContext();
}
You'll also need to remove the context = getActivity(); line from your first test.
I'm following this tutorial and this Custom Detector Example in order to implement Custom Lint Rules. Basically what I've done is:
Create a new Android Project in Android Studio;
Create a java module for project created in step 1;
On module's build.gradle, import Lint API dependencies;
Create an Issue & IssueRegistry & CustomDetector;
Reference the IssueRegistry on module's build.gradle;
Create Unit tests;
My problem is, during the execution of my JUnits, I always receive "No Warning". When I debug the test, I can see that my Custom Detector isn't called, what am I doing wrong?
Strings.java
public class Strings {
public static final String STR_ISSUE_001_ID = "VarsMustHaveMoreThanOneCharacter";
public static final String STR_ISSUE_001_DESCRIPTION = "Avoid naming variables with only one character";
public static final String STR_ISSUE_001_EXPLANATION = "Variables named with only one character do not pass any meaning to the reader. " +
"Variables name should clear indicate the meaning of the value it is holding";
}
Issues.java
public class Issues {
public static final
Issue ISSUE_001 = Issue.create(
STR_ISSUE_001_ID,
STR_ISSUE_001_DESCRIPTION,
STR_ISSUE_001_EXPLANATION,
SECURITY,
// Priority ranging from 0 to 10 in severeness
6,
WARNING,
new Implementation(VariableNameDetector.class, ALL_RESOURCES_SCOPE)
);
}
IssuesRegistry.java
public class IssueRegistry extends com.android.tools.lint.client.api.IssueRegistry {
#Override
public List<Issue> getIssues() {
List<Issue> issues = new ArrayList<>();
issues.add(ISSUE_001);
return issues;
}
}
VariableNameDetector.java
public class VariableNameDetector extends Detector implements Detector.JavaScanner {
public VariableNameDetector() {
}
#Override
public boolean appliesToResourceRefs() {
return false;
}
#Override
public boolean appliesTo(Context context, File file) {
return true;
}
#Override
#Nullable
public AstVisitor createJavaVisitor(JavaContext context) {
return new NamingConventionVisitor(context);
}
#Override
public List<String> getApplicableMethodNames() {
return null;
}
#Override
public List<Class<? extends Node>> getApplicableNodeTypes() {
List<Class<? extends Node>> types = new ArrayList<>(1);
types.add(lombok.ast.VariableDeclaration.class);
return types;
}
#Override
public void visitMethod(
JavaContext context,
AstVisitor visitor,
MethodInvocation methodInvocation
) {
}
#Override
public void visitResourceReference(
JavaContext context,
AstVisitor visitor,
Node node,
String type,
String name,
boolean isFramework
) {
}
private class NamingConventionVisitor extends ForwardingAstVisitor {
private final JavaContext context;
NamingConventionVisitor(JavaContext context) {
this.context = context;
}
#Override
public boolean visitVariableDeclaration(VariableDeclaration node) {
StrictListAccessor<VariableDefinitionEntry, VariableDeclaration> varDefinitions =
node.getVariableDefinitionEntries();
for (VariableDefinitionEntry varDefinition : varDefinitions) {
String name = varDefinition.astName().astValue();
if (name.length() == 1) {
context.report(
ISSUE_001,
context.getLocation(node),
STR_ISSUE_001_DESCRIPTION
);
return true;
}
}
return false;
}
}
}
build.gradle
apply plugin: 'java'
configurations {
lintChecks
}
ext {
VERSION_LINT_API = '24.3.1'
VERSION_LINT_API_TESTS = '24.3.1'
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "com.android.tools.lint:lint-api:$VERSION_LINT_API"
implementation "com.android.tools.lint:lint-checks:$VERSION_LINT_API"
testImplementation "com.android.tools.lint:lint-tests:$VERSION_LINT_API_TESTS"
}
jar {
manifest {
attributes('Lint-Registry': 'br.com.edsilfer.lint_rules.resources.IssueRegistry')
}
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
TestVariableNameDetector.java
private static final String ARG_DEFAULT_LINT_SUCCESS_LOG = "No warnings.";
#Override
protected Detector getDetector() {
return new VariableNameDetector();
}
#Override
protected List<Issue> getIssues() {
return Collections.singletonList(Issues.ISSUE_001);
}
public void test_file_with_no_variables_with_length_equals_01() throws Exception {
assertEquals(
ARG_DEFAULT_LINT_SUCCESS_LOG,
lintProject(java("assets/Test.java", "public class Test {public String sampleVariable;}"))
);
}
public void test_file_with_variables_with_length_equals_01() throws Exception {
assertEquals(
ARG_DEFAULT_LINT_SUCCESS_LOG,
lintProject(java("assets/Test3.java", "public class Test {public String a;bnvhgvhj}"))
);
}
}
P.S.: on Java's module I do not have access to assetsor res folder, that is the reason why I've created a String.java and I'm using java(to, source) in my Unit test - I assumed that this java method does the same as the xml from the tutorial link I referenced at the top of this question.
It turned out that in my case the problem was with the JUnit itself. I think that the way I was attempting to simulate the file was wrong. The text below is part of the README.md of a sample project that I've created in order to document what I've learned from this API and answers the question in the title:
Create
Create a new Android Project;
Create a new Java Library Module - Custom Lint Rules are packaged into .jar libraries once they are ready, therefore the easiest way to implement them using them is inside a Java Module Library;
On module's build.gradle:
add target and source compatibility to Java 1.7;
add dependencies for lint-api, lint-checks and test dependencies;
add jar packing task containing two attributes: Manifest-Version and Lint-Registry, set the first to 1.0 and the second as the full path to a class that will later on contain the issue's catalog;
add a default tasl assemble;
[OPTIONAL]: add a task that will copy the generated .jar into ~/.android/lint;
Check REF001 and choose a Detector that best suits your needs, based on it create and implement a class to fulfill the Detector's role;
Still based on REF0001 chosen file, create and implement a Checker class, later referring to it inside Detector's createJavaVisitor() method;
for the sake of SRP, do not place Checker in the same file of Detector's class;
Copy the generated .jar file from build/lib to ~/.android/lint - if you added a task on build.gradle that does this you can skip this step;
Restart the computer - once created and moved into ~/.android/lint, the Custom Rules should be read by Lint next time the program starts. In order to have the alert boxes inside Android Studio, it is enough to invalidate caches and restart the IDE, however, to have your custom rules caught on Lint Report when ./gradlew check, it might be necessary to restart your computer;
Testing Detectors and Checkers
Testing Custom Rules is not an easy task to do - mainly due the lack of documentation for official APIs. This section will present two approaches for dealing with this. The main goal of this project is to create custom rules that will be run against real files, therefore, test files will be necessary for testing them. They can be places in src/test/resources folder from your Lint Java Library Module;
Approach 01: LintDetectorTest
Make sure you've added all test dependencies - checkout sample project's build.gradle;
Copy EnhancedLintDetectorTest.java and FileUtils.java into your project's test directory;
There is a known bug with Android Studio that prevents it from seeing files from src/test/resources folder, these files are a workaround for that;
EnhancedLintDetectorTest.java should return all issues that will be subject of tests. A nice way to do so is getting them from Issue Registry;
Create a test class that extends from EnhancedLintDetectorTest.java;
Implement getDetector() method returning an instance of the Detector to be tested;
Use lintFiles("test file path taking resources dir as root") to perform the check of the Custom Rules and use its result object to assert the tests;
Note that LintDetectorTest.java derives from TestCase.java, therefore, you're limited to JUnit 3.
Approach 02: Lint JUnit Rule
You might have noticed that Approach 01 might be a little overcomplicated, despite the fact that you're limited to JUnit 3 features. Because of that GitHub user a11n created a Lint JUnit Rule that allows the test of Custom Lint Rules in a easier way that counts with JUnit 4 and up features. Please, refer to his project README.md for details about how to create tests using this apprach.
Currently, Lint JUnit Rule do not correct the root dir for test files and you might no be able to see the tests passing from the IDE - however it works when test are run from command line. An issue and PR were created in order to fix this bug.
I'm not sure how to use the AST Api, however I'm personally using Psi and this is one of my lint checks that are working for me.
public final class RxJava2MethodCheckReturnValueDetector extends Detector implements Detector.JavaPsiScanner {
static final Issue ISSUE_METHOD_MISSING_CHECK_RETURN_VALUE =
Issue.create("MethodMissingCheckReturnValue", "Method is missing the #CheckReturnValue annotation",
"Methods returning RxJava Reactive Types should be annotated with the #CheckReturnValue annotation.",
MESSAGES, 8, WARNING,
new Implementation(RxJava2MethodCheckReturnValueDetector.class, EnumSet.of(JAVA_FILE, TEST_SOURCES)));
#Override public List<Class<? extends PsiElement>> getApplicablePsiTypes() {
return Collections.<Class<? extends PsiElement>>singletonList(PsiMethod.class);
}
#Override public JavaElementVisitor createPsiVisitor(#NonNull final JavaContext context) {
return new CheckReturnValueVisitor(context);
}
static class CheckReturnValueVisitor extends JavaElementVisitor {
private final JavaContext context;
CheckReturnValueVisitor(final JavaContext context) {
this.context = context;
}
#Override public void visitMethod(final PsiMethod method) {
final PsiType returnType = method.getReturnType();
if (returnType != null && Utils.isRxJava2TypeThatRequiresCheckReturnValueAnnotation(returnType)) {
final PsiAnnotation[] annotations = method.getModifierList().getAnnotations();
for (final PsiAnnotation annotation : annotations) {
if ("io.reactivex.annotations.CheckReturnValue".equals(annotation.getQualifiedName())) {
return;
}
}
final boolean isMethodMissingCheckReturnValueSuppressed = context.getDriver().isSuppressed(context, ISSUE_METHOD_MISSING_CHECK_RETURN_VALUE, method);
if (!isMethodMissingCheckReturnValueSuppressed) {
context.report(ISSUE_METHOD_MISSING_CHECK_RETURN_VALUE, context.getLocation(method.getNameIdentifier()), "Method should have #CheckReturnValue annotation");
}
}
}
}
}
Checkout the many more I wrote here.
I am currently starting to unit test my android application. I am having problems when the unit test exercise code that has log statements in it. Here is a specific case. I have a class called ServiceManager that has a setSystemPause() and a getSystemPause() method. I just want a simple unit test that exercise that logic
ServiceManager class:
public class ServiceManager implements IServiceManager {
private final static String TAG = "ServiceManager";
private boolean mSystemPauseStatus = false;
public boolean getSystemPause () {
Log.i ("TAG", "getSystemPause: " + mSystemPauseStatus);
return mSystemPauseStatus;
}
public void setSystemPause (boolean pauseStatus){
Log.i ("TAG", "setSystemPause: " + pauseStatus);
mSystemPauseStatus = pauseStatus;
}
}
The unit test:
public class ServiceManagerTest {
#Test
public void testSystemPause() throws Exception {
ServiceManager serviceManager = new ServiceManager();
serviceManager.setSystemPause(false);
assert (! serviceManager.getSystemPause());
serviceManager.setSystemPause(true);
assert (serviceManager.getSystemPause());
}
}
The problem are the "Log.i" statements in my code. That causes the following error:
java.lang.RuntimeException: Method i in android.util.Log not mocked.
I understand what is happening, during unit test the android.jar library that is used does not contain the real code and I need to mock that call to "Log.i".
But the code base that I am going to test contains a lot of Log statements. I don't want to mock each usage of the Log facility.
My question is how do people do unit testing in Android while having Log statements in their code. Is there another log facility that I can use in my code instead of the Log class.
I also read the page here:
https://developer.android.com/training/testing/unit-testing/local-unit-tests.html
They suggest doing this in my build.gradle file:
android {
...
testOptions {
unitTests.returnDefaultValues = true
}
}
I don't want to resort to that because I just want the Log to appear. I want to properly mock all other facilities I will use in Android.
But will the Log statement affect the outcome of your unit tests? Problem is that Log is an Android-specific class, and can't be used as part of a JUnit 4 test as it's not part of the Java JDK. If you need Log statements to work as intended, either mock the behaviour out with Mockito, use returnDefaultValues = true, or run the test as a Connected Android Test (/androidTest folder instead of /test).
I personally use returnDefaultValues = true as you mention as Logging is something I'm not usually interested in when Unit Testing, only when I'm trying to track down specific bugs.
You could create a package level method in ServiceManager class which calls Log.i method.
public class ServiceManager implements IServiceManager {
private final static String TAG = "ServiceManager";
private boolean mSystemPauseStatus = false;
public boolean getSystemPause () {
log("TAG", "getSystemPause: " + pauseStmSystemPauseStatusatus);
return mSystemPauseStatus;
}
public void setSystemPause (boolean pauseStatus){
log("TAG", "setSystemPause: " + pauseStatus);
mSystemPauseStatus = pauseStatus;
}
void log(String tag, String message) {
Log.i (tag, message);
}
Then you can override this method in ServiceManagerTest to provide no implementation.
public class ServiceManagerTest {
#Test
public void testSystemPause() throws Exception {
ServiceManager serviceManager = createServiceManager();
serviceManager.setSystemPause(false);
assert (! serviceManager.getSystemPause());
serviceManager.setSystemPause(true);
assert (serviceManager.getSystemPause());
}
private ServiceManager createServiceManager() {
return new ServiceManager() {
#Override
void log(String tag, String message) {
//Do nothing or you could test that this method was called.
}
}
}
}
Using: Cucumber-JVM with Android Instrumentation + Espresso).
Reference Github link: https://github.com/mfellner/cucumber-android for this. The simple sample works fine.
Problem with cucumber-jvm + android instrumentation:
But in the sample in link, it uses ActivityInstrumentationTestCase2 which is deprecated. I would like to use #Rule - ActivityTestRule class as said by Google.
Here my question is:
For using cucumber-jvm, I am using the CucumberInstrumentationCore instead of
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner".
So Android junit annotations like #Rule for ActivityTestRule is not parsed by CucumberInstrumentation. So Is it possible to overcome this problem?
Then is my decision to use cucumber-jvm + android instrumentation has to be reverted back. My question is not only for the deprecated class but globally is it good idea to go for cucumber-jvm + android instrumentation, as it can't use instrumentation features because of annotation parsing.
Your runner should inherit from Android JUnitRunner:
public class Instrumentation extends AndroidJUnitRunner {
private final CucumberInstrumentationCore instrumentationCore = new CucumberInstrumentationCore(this);
#Override
public void onCreate(final Bundle bundle) {
instrumentationCore.create(bundle);
super.onCreate(bundle);
}
#Override
public void onStart() {
waitForIdleSync();
instrumentationCore.start();
}
Pay attention to the super class been initialized at the end of onCreate.
Then, edit your defaultConfig in your build.grade file:
defaultConfig {
applicationId "your.package.name"
testApplicationId "your.steps.package"
testInstrumentationRunner "your.package.Instrumentation"
}
And finally, the steps definition class, which inherited from ActivityInstrumentationTestCase2 should look like:
public class BaseStepDefinitions {
public static final String TAG = BaseStepDefinitions.class.getSimpleName();
#Rule
public ActivityTestRule<StartupActivity> mActivityRule = new ActivityTestRule<>(StartupActivity.class);
#Before
public void setUp() throws Exception {
mActivityRule.launchActivity(null);
mActivityRule.getActivity();
}
/**
* All the clean up of application's data and state after each scenario must happen here
*/
#After
public void tearDown() throws Exception {
}
#When("^I login with \"([^\"]*)\" and \"([^\"]*)\"$")
public void i_login_with_and(String user, String password) throws Throwable {
// Login...
}
The setUp function runs before each scenario, and launching the activity.
Globally, if it serves your needs I don't see any problem using it like so, both Cucumber annotations and the JUnit annotations can be parsed in this way.
I've created a sample project: github.com/Clutcha/EspressoCucumber
So after spending a day or so trying to get robolectric to work with gradle using the android-gradle-plpugin I read that the creator thinks it's too much hassle and doesn't use it himself
So thats a big enough reason for me not to use it either. However now I cannot find any docs on how to set up normal android tests to run on the emulator. Its seems they all relate to eclipse. How do I get normal Android testings running with Android studio. I presume I need to modify build.gradle but how do I do that?
I would also like to use roboguice to inject my dependencies into the test cases.
EDIT
So I took a stab in the dark and I tried this but the test returns false (a fail)
public class SearchTest extends ActivityTestCase {
#Inject
private ObjectMapper objectMapper;
#Override
protected void setUp() throws Exception {
super.setUp();
RoboInjector injector = RoboGuice.getInjector(getActivity());
injector.injectMembersWithoutViews(this);
}
public void shouldSerialise() {
System.out.println("called should serialise");
Assert.assertNotNull(objectMapper);
}
}
EDIT 2
So I have tried a different approach. I followed this tutorial which does seem to run the test however I am having a problem with providing a manifest find as I get the following error,
WARNING: No manifest file found at ./AndroidManifest.xml.Falling back
to the Android OS resources only. To remove this warning, annotate
your test class with #Config(manifest=Config.NONE).
I then used this test runner instead...
public class RobolectricGradleTestRunner extends RobolectricTestRunner {
public RobolectricGradleTestRunner(Class<?> testClass) throws org.junit.runners.model.InitializationError {
super(testClass);
}
#Override protected AndroidManifest getAppManifest(Config config) {
String manifestProperty = System.getProperty("android.manifest");
if (config.manifest().equals(Config.DEFAULT) && manifestProperty != null) {
String resProperty = System.getProperty("android.resources");
String assetsProperty = System.getProperty("android.assets");
return new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty),
Fs.fileFromPath(assetsProperty));
}
return super.getAppManifest(config);
}
}
With no luck. Would I be better reverting back to intellij and purely using maven?