• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Rules for running robolectric tests.
2#
3# Uses the following variables:
4#
5#   LOCAL_JAVA_LIBRARIES
6#   LOCAL_STATIC_JAVA_LIBRARIES
7#   LOCAL_ROBOTEST_FAILURE_FATAL
8#   LOCAL_ROBOTEST_TIMEOUT
9#   LOCAL_TEST_PACKAGE
10#   LOCAL_ROBOTEST_FILES
11#   ROBOTEST_FAILURE_FATAL
12#   ROBOTEST_FILTER
13#   ROBOTEST_RUN_INDIVIDUALLY
14#
15#
16# If ROBOTEST_FAILURE_FATAL is set to true then failing tests will cause a
17# build failure. Otherwise failures will be logged but ignored by make.
18#
19# If ROBOTEST_FILTER is set to a regex then only tests matching that pattern
20# will be run. This currently only works at the class level.
21#
22# TODO: Switch to a JUnit runner which can support method-level test
23# filtering and use that rather than grep to implement ROBOTEST_FILTER.
24#
25# If ROBOTEST_RUN_INDIVIDUALLY is set to true, each test class will be run by a
26# different JVM, preventing any interaction between different tests. This is
27# significantly slower than running all tests within the same JVM, but prevents
28# unwanted interactions.
29#
30# Tests classes are found by looking for *Test.java files in
31# LOCAL_PATH recursively.
32
33################################################
34# General settings, independent of the module. #
35################################################
36
37### Used for running tests.
38ifneq ($(DISABLE_ROBO_RUN_TESTS),true)
39    # Where to find Robolectric.
40    my_robolectric_script_path := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
41
42    my_collect_target := $(LOCAL_MODULE)-coverage
43    my_report_target := $(LOCAL_MODULE)-jacoco
44    .PHONY: $(my_collect_target) $(my_report_target)
45    # Whether or not to ignore the result of running the robotests.
46    # LOCAL_ROBOTEST_FAILURE_FATAL will take precedence over ROBOTEST_FAILURE_FATAL,
47    # if present.
48    my_failure_fatal := $(if $(LOCAL_ROBOTEST_FAILURE_FATAL)$(ROBOTEST_FAILURE_FATAL),true,false)
49    # The timeout for the command. A value of '0' means no timeout. The default is
50    # 10 minutes.
51    my_timeout := $(if $(LOCAL_ROBOTEST_TIMEOUT),$(LOCAL_ROBOTEST_TIMEOUT),600)
52    # Command to filter the list of test classes.
53    # If not specified, defaults to including all the tests.
54    my_test_filter_command := $(if $(ROBOTEST_FILTER),grep -E "$(ROBOTEST_FILTER)",)
55
56    # The directory containing the sources.
57    my_instrument_makefile_dir := $(dir $(ALL_MODULES.$(LOCAL_TEST_PACKAGE).MAKEFILE))
58    my_instrument_source_dirs := $(if $(LOCAL_INSTRUMENT_SOURCE_DIRS),\
59        $(LOCAL_INSTRUMENT_SOURCE_DIRS),\
60        $(my_instrument_makefile_dir)src $(my_instrument_makefile_dir)java)
61
62    my_instrument_srcjars := $(LOCAL_INSTRUMENT_SRCJARS)
63
64    ##########################
65    # Used by base_rules.mk. #
66    ##########################
67
68    LOCAL_MODULE_CLASS := ROBOLECTRIC
69    # This is actually a phony target that is never built.
70    LOCAL_BUILT_MODULE_STEM := test.fake
71    # Since it is not built, it cannot be installed. But we will define our own
72    # dist files, depending on which of the specific targets is invoked.
73    LOCAL_UNINSTALLABLE_MODULE := true
74    # Do not build it for checkbuild or mma
75    LOCAL_DONT_CHECK_MODULE := true
76
77    include $(BUILD_SYSTEM)/base_rules.mk
78
79
80    #############################
81    # Module specific settings. #
82    #############################
83
84    ### Used for running tests.
85
86    # The list of test classes. Robolectric requires an explicit list of tests to
87    # run, which is compiled from the Java files ending in "Test" within the
88    # directory from which this module is invoked.
89    ifeq ($(strip $(LOCAL_ROBOTEST_FILES)),)
90        LOCAL_ROBOTEST_FILES := $(call find-files-in-subdirs,$(LOCAL_PATH)/src,*Test.java,.)
91        LOCAL_ROBOTEST_FILES += $(call find-files-in-subdirs,$(LOCAL_PATH)/src,*Test.kt,.)
92    endif
93    # Convert the paths into package names by removing .java or *.kt extensions and replacing "/" with "."
94    my_tests := $(sort $(subst /,.,$(basename $(LOCAL_ROBOTEST_FILES))))
95    ifdef my_test_filter_command
96        my_tests := $(sort $(shell echo '$(my_tests)' | tr ' ' '\n' | $(my_test_filter_command)))
97    endif
98    # The source jars containing the tests.
99    my_srcs_jars := \
100        $(foreach lib, \
101            $(LOCAL_JAVA_LIBRARIES) $(LOCAL_STATIC_JAVA_LIBRARIES), \
102            $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/classes-pre-proguard.jar) \
103        $(foreach lib, \
104            $(LOCAL_TEST_PACKAGE), \
105            $(call intermediates-dir-for,APPS,$(lib),,COMMON)/classes-pre-proguard.jar)
106    # The jars needed to run the tests.
107    my_jars := \
108        $(my_robolectric_jars) \
109        $(call java-lib-files,robolectric-host-android_all,HOST) \
110        $(call java-lib-files,junitxml) \
111        $(my_srcs_jars)
112
113
114
115    # Run tests.
116    my_phony_target := $(LOCAL_MODULE)
117    my_target := $(LOCAL_BUILT_MODULE)
118    my_filename_stem := test
119
120    # Define rules that copy android-all jars to the intermediates folder.
121    local_android_all_source_jar := $(call java-lib-files,robolectric-host-android_all,HOST)
122    android_all_lib_path := prebuilts/misc/common/robolectric/android-all
123    my_robolectric_path := $(intermediates.COMMON)/android-all
124    copy_android_all_jar_pairs := \
125      $(android_all_lib_path)/android-all-4.1.2_r1-robolectric-r1.jar:$(my_robolectric_path)/android-all-4.1.2_r1-robolectric-r1.jar \
126      $(android_all_lib_path)/android-all-4.2.2_r1.2-robolectric-r1.jar:$(my_robolectric_path)/android-all-4.2.2_r1.2-robolectric-r1.jar \
127      $(android_all_lib_path)/android-all-4.3_r2-robolectric-r1.jar:$(my_robolectric_path)/android-all-4.3_r2-robolectric-r1.jar \
128      $(android_all_lib_path)/android-all-4.4_r1-robolectric-r2.jar:$(my_robolectric_path)/android-all-4.4_r1-robolectric-r2.jar \
129      $(android_all_lib_path)/android-all-5.0.2_r3-robolectric-r0.jar:$(my_robolectric_path)/android-all-5.0.2_r3-robolectric-r0.jar \
130      $(android_all_lib_path)/android-all-5.1.1_r9-robolectric-r2.jar:$(my_robolectric_path)/android-all-5.1.1_r9-robolectric-r2.jar \
131      $(android_all_lib_path)/android-all-6.0.1_r3-robolectric-r1.jar:$(my_robolectric_path)/android-all-6.0.1_r3-robolectric-r1.jar \
132      $(android_all_lib_path)/android-all-7.0.0_r1-robolectric-r1.jar:$(my_robolectric_path)/android-all-7.0.0_r1-robolectric-r1.jar \
133      $(android_all_lib_path)/android-all-7.1.0_r7-robolectric-r1.jar:$(my_robolectric_path)/android-all-7.1.0_r7-robolectric-r1.jar \
134      $(android_all_lib_path)/android-all-8.0.0_r4-robolectric-r1.jar:$(my_robolectric_path)/android-all-8.0.0_r4-robolectric-r1.jar \
135      $(android_all_lib_path)/android-all-8.1.0-robolectric-4611349.jar:$(my_robolectric_path)/android-all-8.1.0-robolectric-4611349.jar \
136      $(android_all_lib_path)/android-all-9-robolectric-4913185-2.jar:$(my_robolectric_path)/android-all-9-robolectric-4913185-2.jar \
137      $(android_all_lib_path)/android-all-10-robolectric-5803371.jar:$(my_robolectric_path)/android-all-10-robolectric-5803371.jar \
138      $(android_all_lib_path)/android-all-11-robolectric-6757853.jar:$(my_robolectric_path)/android-all-11-robolectric-6757853.jar \
139      $(android_all_lib_path)/android-all-12-robolectric-7732740.jar:$(my_robolectric_path)/android-all-12-robolectric-7732740.jar \
140      $(android_all_lib_path)/android-all-12.1-robolectric-8229987.jar:$(my_robolectric_path)/android-all-12.1-robolectric-8229987.jar \
141      $(android_all_lib_path)/android-all-13-robolectric-9030017.jar:$(my_robolectric_path)/android-all-13-robolectric-9030017.jar \
142      $(local_android_all_source_jar):$(my_robolectric_path)/android-all-current-robolectric-r0.jar
143    copy_android_all_jars := $(call copy-many-files, $(copy_android_all_jar_pairs))
144
145    $(my_target): $(copy_android_all_jars)
146
147    include $(my_robolectric_script_path)/robotest-internal.mk
148    # clean local variables
149    my_java_args :=
150    my_phony_target :=
151    my_target :=
152
153    # Target for running robolectric tests using jacoco
154    my_phony_target := $(my_report_target)
155    my_target := $(LOCAL_BUILT_MODULE)-coverage
156    my_collect_file := $(my_target)
157    my_filename_stem := coverage
158    $(my_collect_target): $(my_target)
159    $(my_target): $(call java-lib-files,jvm-jacoco-agent,true) $(copy_android_all_jars)
160
161    my_coverage_dir := $(intermediates)/coverage
162    my_coverage_file := $(my_coverage_dir)/jacoco.exec
163
164    # List of packages to exclude jacoco from running
165    my_jacoco_excludes := \
166        org.robolectric.* \
167        org.mockito.* \
168        org.junit.* \
169        org.objectweb.* \
170        com.thoughtworks.xstream.*
171    # The Jacoco agent JAR.
172    my_jacoco_agent_jar := $(call java-lib-files,jvm-jacoco-agent,true)
173    # Using Jacoco with Robolectric is broken in 0.7.3 <= version < 0.7.6.
174    # In 0.7.6 or above, the parameter "inclnolocationclasses" is needed.
175    # See https://github.com/jacoco/jacoco/pull/288 for more
176    # In JDK9, if "inclnolocationclasses" is used, we also need to specify
177    # exclclassloader=jdk.internal.reflect.DelegatingClassLoader
178    # https://github.com/jacoco/jacoco/issues/16
179    my_jacoco_agent_args = \
180        destfile=$(my_coverage_file) \
181        excludes=$(call normalize-path-list, $(my_jacoco_excludes)) \
182        inclnolocationclasses=true \
183        exclclassloader=jdk.internal.reflect.DelegatingClassLoader \
184        append=false
185    my_java_args := \
186        -javaagent:$(my_jacoco_agent_jar)=$(call normalize-comma-list, $(my_jacoco_agent_args))
187    include $(my_robolectric_script_path)/robotest-internal.mk
188    # Clear temporary variables
189    my_failure_fatal :=
190    my_jacoco_agent_jar :=
191    my_jacoco_agent_args :=
192    my_jacoco_excludes :=
193    my_java_args :=
194    my_phony_target :=
195    my_robolectric_jars :=
196    my_target :=
197    my_tests :=
198    my_filename_stem :=
199
200    # Target for generating code coverage reports using jacoco.exec
201    my_target := $(LOCAL_BUILT_MODULE)-jacoco
202    $(my_report_target): $(my_target)
203
204    # The JAR file containing the report generation tool.
205    my_coverage_report_class := com.google.android.jacoco.reporter.ReportGenerator
206    my_coverage_report_jar := $(call java-lib-files,jvm-jacoco-reporter,true)
207    my_coverage_srcs_jars := $(my_srcs_jars)
208    my_coverage_report_dist_file := $(my_report_target)-html.zip
209
210    ## jacoco code coverage reports
211    include $(my_robolectric_script_path)/report-internal.mk
212    # Clear temporary variables
213    my_coverage_dir :=
214    my_coverage_file :=
215    my_coverage_report_class :=
216    my_coverage_report_dist_file :=
217    my_coverage_report_jar :=
218    my_coverage_srcs_jars :=
219    my_robolectric_script_path :=
220    my_robolectric_path :=
221    my_srcs_jars :=
222    my_target :=
223    my_collect_file :=
224
225    my_instrument_makefile_dir :=
226    my_instrument_source_dirs :=
227    my_instrument_srcjars :=
228endif
229