Skip to content

Commit

Permalink
Add support for ios_unit_test and ios_ui_test for depending on ios_fr…
Browse files Browse the repository at this point in the history
…amework targets.

This should help with sharing resource and linking actions for sets of tests where there are shared dependencies, which would otherwise be processed for each test bundle.

RELNOTES: ios_unit_test and ios_ui_test now accept a `frameworks` attribute which can link to `ios_framework` targets. This allows sharing of code and resources across multiple test targets that contain common dependencies, and avoids the duplicate processing actions for those.
PiperOrigin-RevId: 259823396
  • Loading branch information
sergiocampama authored and swiple-rules-gardener committed Jul 24, 2019
1 parent e23116f commit ba29516
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 5 deletions.
9 changes: 8 additions & 1 deletion apple/internal/testing/apple_test_bundle_support.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ def _apple_test_bundle_impl(ctx, extra_providers = []):
debug_outputs_provider = binary_descriptor.debug_outputs_provider

debug_dependencies = []
targets_to_avoid = []
if hasattr(ctx.attr, "frameworks"):
targets_to_avoid = list(ctx.attr.frameworks)
else:
targets_to_avoid = []
product_type = ctx.attr._product_type
if ctx.attr.test_host:
debug_dependencies.append(ctx.attr.test_host)
Expand All @@ -92,6 +95,10 @@ def _apple_test_bundle_impl(ctx, extra_providers = []):
debug_dependencies = debug_dependencies,
debug_outputs_provider = debug_outputs_provider,
),
partials.embedded_bundles_partial(
bundle_embedded_bundles = True,
embeddable_targets = getattr(ctx.attr, "frameworks", default = []),
),
partials.framework_import_partial(
targets = ctx.attr.deps,
targets_to_avoid = targets_to_avoid,
Expand Down
7 changes: 6 additions & 1 deletion apple/ios.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,11 @@ def ios_ui_test(
**kwargs
)

_ios_ui_test(name = name, **bundling_args)
_ios_ui_test(
name = name,
dylibs = kwargs.get("frameworks"),
**bundling_args
)

def ios_ui_test_suite(name, runners = [], **kwargs):
"""Builds an XCUITest test suite with the given runners.
Expand Down Expand Up @@ -205,6 +209,7 @@ def ios_unit_test(
bundle_loader = test_host
_ios_unit_test(
name = name,
dylibs = kwargs.get("frameworks"),
bundle_loader = bundle_loader,
test_host = test_host,
**bundling_args
Expand Down
40 changes: 40 additions & 0 deletions doc/rules-ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,16 @@ of the attributes inherited by all test rules, please check the
"Tests" suffix.</p>
</td>
</tr>
<tr>
<td><code>frameworks</code></td>
<td>
<p><code>List of <a href="https://bazel.build/versions/master/docs/build-ref.html#labels">labels</a>; optional</code></p>
<p>A list of framework targets (see <a href="#ios_framework"><code>ios_framework</code></a>)
that this test depends on. Frameworks can be used for consolidating code
and resources that might be shared across multiple tests, so that they
do not get processed once per test target.</p>
</td>
</tr>
<tr>
<td><code>infoplists</code></td>
<td>
Expand Down Expand Up @@ -1345,6 +1355,16 @@ Builds an XCUITest test suite with the given runners.
test execution.</p>
</td>
</tr>
<tr>
<td><code>frameworks</code></td>
<td>
<p><code>List of <a href="https://bazel.build/versions/master/docs/build-ref.html#labels">labels</a>; optional</code></p>
<p>A list of framework targets (see <a href="#ios_framework"><code>ios_framework</code></a>)
that this test depends on. Frameworks can be used for consolidating code
and resources that might be shared across multiple tests, so that they
do not get processed once per test target.</p>
</td>
</tr>
<tr>
<td><code>infoplists</code></td>
<td>
Expand Down Expand Up @@ -1487,6 +1507,16 @@ of the attributes inherited by all test rules, please check the
test execution.</p>
</td>
</tr>
<tr>
<td><code>frameworks</code></td>
<td>
<p><code>List of <a href="https://bazel.build/versions/master/docs/build-ref.html#labels">labels</a>; optional</code></p>
<p>A list of framework targets (see <a href="#ios_framework"><code>ios_framework</code></a>)
that this test depends on. Frameworks can be used for consolidating code
and resources that might be shared across multiple tests, so that they
do not get processed once per test target.</p>
</td>
</tr>
<tr>
<td><code>infoplists</code></td>
<td>
Expand Down Expand Up @@ -1607,6 +1637,16 @@ Builds an XCTest unit test suite with the given runners.
test execution.</p>
</td>
</tr>
<tr>
<td><code>frameworks</code></td>
<td>
<p><code>List of <a href="https://bazel.build/versions/master/docs/build-ref.html#labels">labels</a>; optional</code></p>
<p>A list of framework targets (see <a href="#ios_framework"><code>ios_framework</code></a>)
that this test depends on. Frameworks can be used for consolidating code
and resources that might be shared across multiple tests, so that they
do not get processed once per test target.</p>
</td>
</tr>
<tr>
<td><code>infoplists</code></td>
<td>
Expand Down
70 changes: 69 additions & 1 deletion test/ios_ui_test_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,24 @@ function create_common_files() {
load("@build_bazel_rules_apple//apple:ios.bzl",
"ios_application",
"ios_ui_test",
"ios_framework",
)
objc_library(
name = "lib",
srcs = ["main.m"],
)
objc_library(
name = "shared_test_lib",
hdrs = ["TestShared.h"],
srcs = ["TestShared.m"],
)
objc_library(
name = "ui_test_lib",
srcs = ["UITest.m"],
deps = [":shared_test_lib"],
)
EOF

Expand All @@ -54,11 +62,32 @@ EOF

cat > app/UITest.m <<EOF
#import <XCTest/XCTest.h>
#import "app/TestShared.h"
@interface UITest: XCTestCase
@end
@implementation UITest
- (void)testAssertNil { XCTAssertNil(nil); }
- (void)testAssertNil {
// Call the shared method to ensure it is properly linked.
[[[TestShared alloc] init] doSomething];
XCTAssertNil(nil);
}
@end
EOF

cat > app/TestShared.h <<EOF
#import <Foundation/Foundation.h>
@interface TestShared: NSObject
- (void)doSomething;
@end
EOF

cat > app/TestShared.m <<EOF
#import "app/TestShared.h"
@implementation TestShared
- (void)doSomething { }
@end
EOF

Expand Down Expand Up @@ -220,4 +249,43 @@ function test_dsyms_generated() {
done
}

# Tests that test bundles can depend on ios_frameworks.
function test_target_can_depend_on_ios_framework() {
create_common_files

cat >> app/BUILD <<EOF
ios_application(
name = "app",
bundle_id = "my.bundle.id",
families = ["iphone"],
infoplists = ["Info.plist"],
minimum_os_version = "9.0",
provisioning_profile = "@build_bazel_rules_apple//test/testdata/provisioning:integration_testing_ios.mobileprovision",
deps = [":lib"],
)
ios_framework(
name = "test_framework",
bundle_id = "my.test.shared.framework",
infoplists = ["Info.plist"],
minimum_os_version = "9.0",
families = ["iphone", "ipad"],
deps = [":shared_test_lib"],
)
ios_ui_test(
name = "ui_tests",
deps = [":ui_test_lib"],
frameworks = [":test_framework"],
minimum_os_version = "9.0",
test_host = ":app",
)
EOF

do_build ios //app:ui_tests || fail "Should build"

assert_zip_contains "test-bin/app/ui_tests.zip" \
"ui_tests.xctest/Frameworks/test_framework.framework/test_framework"
}

run_suite "ios_ui_test bundling tests"
72 changes: 70 additions & 2 deletions test/ios_unit_test_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function create_common_files() {
load("@build_bazel_rules_apple//apple:ios.bzl",
"ios_application",
"ios_unit_test",
"ios_framework",
)
load("@build_bazel_rules_swift//swift:swift.bzl",
"swift_library"
Expand All @@ -43,9 +44,16 @@ objc_library(
srcs = ["main.m"],
)
objc_library(
name = "shared_test_lib",
hdrs = ["TestShared.h"],
srcs = ["TestShared.m"],
)
objc_library(
name = "unit_test_lib",
srcs = ["UnitTest.m"],
deps = [":shared_test_lib"],
)
EOF

Expand All @@ -57,11 +65,32 @@ EOF

cat > app/UnitTest.m <<EOF
#import <XCTest/XCTest.h>
#import "app/TestShared.h"
@interface UnitTest: XCTestCase
@end
@implementation UnitTest
- (void)testAssertNil { XCTAssertNil(nil); }
- (void)testAssertNil {
// Call the shared method to ensure it is properly linked.
[[[TestShared alloc] init] doSomething];
XCTAssertNil(nil);
}
@end
EOF

cat > app/TestShared.h <<EOF
#import <Foundation/Foundation.h>
@interface TestShared: NSObject
- (void)doSomething;
@end
EOF

cat > app/TestShared.m <<EOF
#import "app/TestShared.h"
@implementation TestShared
- (void)doSomething { }
@end
EOF

Expand Down Expand Up @@ -259,7 +288,7 @@ ios_application(
objc_library(
name = "unit_test_lib_with_swift",
srcs = ["UnitTest.m"],
deps = [":swiftlib"],
deps = [":swiftlib", ":shared_test_lib"],
)
swift_library(
Expand Down Expand Up @@ -640,4 +669,43 @@ function test_select_on_linkopts() {
do_build ios //app:unit_tests || fail "Should build"
}

# Tests that test bundles can depend on ios_frameworks.
function test_target_can_depend_on_ios_framework() {
create_common_files

cat >> app/BUILD <<EOF
ios_application(
name = "app",
bundle_id = "my.bundle.id",
families = ["iphone"],
infoplists = ["Info.plist"],
minimum_os_version = "9.0",
provisioning_profile = "@build_bazel_rules_apple//test/testdata/provisioning:integration_testing_ios.mobileprovision",
deps = [":lib"],
)
ios_framework(
name = "test_framework",
bundle_id = "my.test.shared.framework",
infoplists = ["Info.plist"],
minimum_os_version = "9.0",
families = ["iphone", "ipad"],
deps = [":shared_test_lib"],
)
ios_unit_test(
name = "unit_tests",
deps = [":unit_test_lib"],
frameworks = [":test_framework"],
minimum_os_version = "9.0",
test_host = ":app",
)
EOF

do_build ios //app:unit_tests || fail "Should build"

assert_zip_contains "test-bin/app/unit_tests.zip" \
"unit_tests.xctest/Frameworks/test_framework.framework/test_framework"
}

run_suite "ios_unit_test bundling tests"

0 comments on commit ba29516

Please sign in to comment.