diff --git a/README.md b/README.md index a32e18ffca7a..7e8e16baa09b 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,10 @@ Finally, update `[PROJECT_ROOT]\.git\info\exclude` to ignore the symlink locally # assets symlink WordPressEditor/src/main/assets +## Testing ## + +Testing is done with the [Robolectric framework.](http://robolectric.org/) To run tests simply run `gradlew testDebug`. Code coverage reports can be generated via [JaCoCo.](http://www.eclemma.org/jacoco/) To generate them locally run `gradlew jacocoTestReport`. + ## LICENSE ## -WordPress-Editor-Android is an Open Source project covered by the [GNU General Public License version 2](LICENSE.md). \ No newline at end of file +WordPress-Editor-Android is an Open Source project covered by the [GNU General Public License version 2](LICENSE.md). diff --git a/WordPressEditor/build.gradle b/WordPressEditor/build.gradle index d920ebe99f63..3b2e5bd90b1a 100644 --- a/WordPressEditor/build.gradle +++ b/WordPressEditor/build.gradle @@ -4,10 +4,13 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:1.0.0' + classpath 'org.robolectric:robolectric-gradle-plugin:0.14.1' } } apply plugin: 'com.android.library' +apply plugin: 'robolectric' +apply plugin: 'jacoco' apply plugin: 'maven' apply plugin: 'signing' @@ -40,6 +43,17 @@ dependencies { compile 'com.android.support:support-v4:21.0.+' compile 'org.wordpress:analytics:1.0.0' compile 'org.wordpress:utils:1.5.0' + + // Test libraries + testCompile 'junit:junit:4.10' + testCompile 'org.mockito:mockito-core:1.10.19' + testCompile 'org.robolectric:robolectric:2.4' + + // Workaround for IDE bug + // http://stackoverflow.com/questions/22246183/android-studio-doesnt-recognize-espresso-classes + provided 'junit:junit:4.10' + provided 'org.mockito:mockito-core:1.10.19' + provided 'org.robolectric:robolectric:2.4' } signing { @@ -97,3 +111,45 @@ uploadArchives { } } } + +// +// Testing and code coverage +// + +robolectric { + include '**/*Test.class' + exclude '**/ApplicationTest.class' +} + +jacoco { + toolVersion = "0.7.1.201405082137" +} + +// Use these to define which classes to include and exclude from code coverage analysis +def coverageSourceDirs = [ 'src/main/java' ] +def coverageExclusions = [ '**/R.class', + '**/R$*.class', + '**/*$ViewInjector*.*', + '**/BuildConfig.*', + '**/Manifest*.*', + '**/Legacy**.class', + '**/legacy/**/*.class' ] + +task jacocoTestReport(type: JacocoReport, dependsOn: "testDebug") { + group = "Reporting" + description = "Generate Jacoco coverage reports" + + classDirectories = fileTree( + dir: 'build/intermediates/classes/debug', + excludes: coverageExclusions + ) + + additionalSourceDirs = files(coverageSourceDirs) + sourceDirectories = files(coverageSourceDirs) + executionData = files('build/jacoco/testDebug.exec') + + reports { + xml.enabled = true + html.enabled = true + } +} diff --git a/WordPressEditor/lint.xml b/WordPressEditor/lint.xml new file mode 100644 index 000000000000..b7b4876d98b8 --- /dev/null +++ b/WordPressEditor/lint.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/WordPressEditor/src/androidTest/java/org/wordpress/android/editor/EditorFragmentAbstractTest.java b/WordPressEditor/src/androidTest/java/org/wordpress/android/editor/EditorFragmentAbstractTest.java new file mode 100644 index 000000000000..53e7a31868cb --- /dev/null +++ b/WordPressEditor/src/androidTest/java/org/wordpress/android/editor/EditorFragmentAbstractTest.java @@ -0,0 +1,77 @@ +package org.wordpress.android.editor; + +import android.app.Activity; +import android.text.Spanned; + +import com.android.volley.toolbox.ImageLoader; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.wordpress.android.util.helpers.MediaFile; +import org.wordpress.android.util.helpers.MediaGallery; + +@Config(emulateSdk = 18) +@RunWith(RobolectricTestRunner.class) +public class EditorFragmentAbstractTest { + @Test + public void testActivityMustImplementEditorFragmentListener() { + // Host Activity must implement EditorFragmentListener, exception expected if not + boolean didPassTest = false; + Activity hostActivity = Robolectric.buildActivity(Activity.class).create().get(); + EditorFragmentAbstract testFragment = new DefaultEditorFragment(); + + try { + testFragment.onAttach(hostActivity); + } catch (ClassCastException classCastException) { + didPassTest = true; + } + + Assert.assertTrue(didPassTest); + } + + @Test + public void testOnBackPressReturnsFalseByDefault() { + // The default behavior of onBackPressed should return false + Assert.assertFalse(new DefaultEditorFragment().onBackPressed()); + } + + /** + * Used to test default behavior of non-abstract methods. + */ + public static class DefaultEditorFragment extends EditorFragmentAbstract { + @Override + public void setTitle(CharSequence text) { + } + + @Override + public void setContent(CharSequence text) { + } + + @Override + public CharSequence getTitle() { + return null; + } + + @Override + public CharSequence getContent() { + return null; + } + + @Override + public void appendMediaFile(MediaFile mediaFile, String imageUrl, ImageLoader imageLoader) { + } + + @Override + public void appendGallery(MediaGallery mediaGallery) { + } + + @Override + public Spanned getSpannedContent() { + return null; + } + } +}