• 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-R-beta2-robolectric-6625208.jar:$(my_robolectric_path)/android-all-R-beta2-robolectric-6625208.jar \
139      $(android_all_lib_path)/android-all-S-beta3-robolectric-7541949.jar:$(my_robolectric_path)/android-all-S-beta3-robolectric-7541949.jar \
140      $(local_android_all_source_jar):$(my_robolectric_path)/android-all-current-robolectric-r0.jar
141    copy_android_all_jars := $(call copy-many-files, $(copy_android_all_jar_pairs))
142
143    $(my_target): $(copy_android_all_jars)
144
145    include $(my_robolectric_script_path)/robotest-internal.mk
146    # clean local variables
147    my_java_args :=
148    my_phony_target :=
149    my_target :=
150
151    # Target for running robolectric tests using jacoco
152    my_phony_target := $(my_report_target)
153    my_target := $(LOCAL_BUILT_MODULE)-coverage
154    my_collect_file := $(my_target)
155    my_filename_stem := coverage
156    $(my_collect_target): $(my_target)
157    $(my_target): $(call java-lib-files,jvm-jacoco-agent,true) $(copy_android_all_jars)
158
159    my_coverage_dir := $(intermediates)/coverage
160    my_coverage_file := $(my_coverage_dir)/jacoco.exec
161
162    # List of packages to exclude jacoco from running
163    my_jacoco_excludes := \
164        org.robolectric.* \
165        org.mockito.* \
166        org.junit.* \
167        org.objectweb.* \
168        com.thoughtworks.xstream.*
169    # The Jacoco agent JAR.
170    my_jacoco_agent_jar := $(call java-lib-files,jvm-jacoco-agent,true)
171    # Using Jacoco with Robolectric is broken in 0.7.3 <= version < 0.7.6.
172    # In 0.7.6 or above, the parameter "inclnolocationclasses" is needed.
173    # See https://github.com/jacoco/jacoco/pull/288 for more
174    # In JDK9, if "inclnolocationclasses" is used, we also need to specify
175    # exclclassloader=jdk.internal.reflect.DelegatingClassLoader
176    # https://github.com/jacoco/jacoco/issues/16
177    my_jacoco_agent_args = \
178        destfile=$(my_coverage_file) \
179        excludes=$(call normalize-path-list, $(my_jacoco_excludes)) \
180        inclnolocationclasses=true \
181        exclclassloader=jdk.internal.reflect.DelegatingClassLoader \
182        append=false
183    my_java_args := \
184        -javaagent:$(my_jacoco_agent_jar)=$(call normalize-comma-list, $(my_jacoco_agent_args))
185    include $(my_robolectric_script_path)/robotest-internal.mk
186    # Clear temporary variables
187    my_failure_fatal :=
188    my_jacoco_agent_jar :=
189    my_jacoco_agent_args :=
190    my_jacoco_excludes :=
191    my_java_args :=
192    my_phony_target :=
193    my_robolectric_jars :=
194    my_target :=
195    my_tests :=
196    my_filename_stem :=
197
198    # Target for generating code coverage reports using jacoco.exec
199    my_target := $(LOCAL_BUILT_MODULE)-jacoco
200    $(my_report_target): $(my_target)
201
202    # The JAR file containing the report generation tool.
203    my_coverage_report_class := com.google.android.jacoco.reporter.ReportGenerator
204    my_coverage_report_jar := $(call java-lib-files,jvm-jacoco-reporter,true)
205    my_coverage_srcs_jars := $(my_srcs_jars)
206    my_coverage_report_dist_file := $(my_report_target)-html.zip
207
208    ## jacoco code coverage reports
209    include $(my_robolectric_script_path)/report-internal.mk
210    # Clear temporary variables
211    my_coverage_dir :=
212    my_coverage_file :=
213    my_coverage_report_class :=
214    my_coverage_report_dist_file :=
215    my_coverage_report_jar :=
216    my_coverage_srcs_jars :=
217    my_robolectric_script_path :=
218    my_robolectric_path :=
219    my_srcs_jars :=
220    my_target :=
221    my_collect_file :=
222
223    my_instrument_makefile_dir :=
224    my_instrument_source_dirs :=
225    my_instrument_srcjars :=
226endif
227