Dealing with assets and tests in Android and Java

May 22, 2014 at 4:50 PM
Edited May 23, 2014 at 1:18 AM

The problem

So right now we have a structure where our main project is UniversalUtilities and it contains most of the interesting stuff. Unfortunately some of its code can't be tested without access to a TDH and I can't run a TDH in UniversalUtilities without using content in either AndroidUtilities or JavaUtilities.

I could have fixed this by creating a separate test project but I didn't want to do this because I actually need to run all those tests twice, once using Android and once using Java. So I would end up with two separate test projects. This all felt too complex.

To complicate things further we have HTML and JS files we need for testing and some of our dependencies need for production. A lot of the nastiness in the current Thali setup was driven by the fact that for a long time Android didn't allow assets folders into libraries and AndroidUtilities is a library. So I ended up doing various awful things involving Java Resources. The reason they were awful is that Android doesn't seem to support enumerating the contents of a Java Resources folder in a JAR or doing things like loading a HTML file in a WebView from JAR resources. So we handle assets in a really screwed up way now.

Fixing assets

My proposal is as follows:
  1. Remove all assets from UniversalUtilities
  2. Create androidTest/assets/thali/test to handle our test files and main/assets/thali/production to handle our production files in AndroidUtilities.
  3. Set up a gradle task to copy the assets from AndroidUtilities into the main/resources and test/resources folders in JavaUtilities.
In this model the 'true' copy of the assets is in AndroidUtilities. So any changes must happen there. If changes are made in java they will be overwritten by the gradle copy task (well, mostly because I'll slip a delete in there as well).

Fixing tests

Right now writing tests is a nightmare. You write the test in UniversalUtilities in the production section. Then in AndroidUtilities and JavaUtilities we write wrappers for each test file in the test section. To make things simpler we crunch tests together so each file has one test. It's awful! It means tests get scrunched together. It's error prone. It's fragile. It sucks! The only reason I did this is because I just needed to get something working and this did work for some definition of work.

But it's time to fix it or we'll never write more tests.

My proposal is:
  1. Pull all tests out of UniversalUtilities that can't run there.
  2. Put the tests into AndroidUtilities. This will become the 'true' copy of the tests (just like assets above have their 'true' copy in AndroidUtilities).
  3. Set up gradle to copy the AndroidUtilities tests into JavaUtilities.
  4. Set up gradle to copy the AndroidUtilities tests AND test assets into AndroidPouchDbSDK.
Eventually we'll need to figure out how we want to hook up testing for the TDHs. But we don't have anything in there yet.

Conclusion

So to boil it all down:
  1. All HTML/JS/etc. files (both test and production) live in assets in AndroidUtilities and are copied by Gradle to resources in JavaUtilities
  2. All tests that can't be run in UniversalUtilities will live in AndroidUtilities and be copied to where ever they are needed such as JavaUtilities and AndroidPouchDbSDK.