mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2024-11-10 06:14:38 +03:00
Merge pull request #434 from yonaskolb/test_target
Add TestTarget with parallelizable and randomExecutionOrder
This commit is contained in:
commit
e96c91eecf
@ -6,6 +6,7 @@
|
||||
- Added `weak` linking setting for dependencies [#411](https://github.com/yonaskolb/XcodeGen/pull/411) @alvarhansen
|
||||
- Added `info` to targets for generating an `Info.plist` [#415](https://github.com/yonaskolb/XcodeGen/pull/415) @yonaskolb
|
||||
- Added `entitlements` to targets for generating an `.entitlement` file [#415](https://github.com/yonaskolb/XcodeGen/pull/415) @yonaskolb
|
||||
- Added `parallelizable` and `randomExecutionOrder` to `Scheme` test targets in an expanded form [#434](https://github.com/yonaskolb/XcodeGen/pull/434) @yonaskolb
|
||||
- Validate incorrect config setting definitions [#431](https://github.com/yonaskolb/XcodeGen/pull/431) @yonaskolb
|
||||
- Automatically set project `SDKROOT` if there is only a single platform within the project [#433](https://github.com/yonaskolb/XcodeGen/pull/433) @yonaskolb
|
||||
|
||||
|
@ -454,7 +454,7 @@ targets:
|
||||
This is a convenience used to automatically generate schemes for a target based on different configs or included tests. If you want more control check out the top level [Scheme](#scheme).
|
||||
|
||||
- [x] **configVariants**: **[String]** - This generates a scheme for each entry, using configs that contain the name with debug and release variants. This is useful for having different environment schemes.
|
||||
- [ ] **testTargets**: **[String]** - a list of test targets that should be included in the scheme. These will be added to the build targets and the test entries
|
||||
- [ ] **testTargets**: **[[Test Target](#test-target)]** - a list of test targets that should be included in the scheme. These will be added to the build targets and the test entries. Each entry can either be a simple string, or a [Test Target](#test-target)
|
||||
- [ ] **gatherCoverageData**: **Bool** - a boolean that indicates if this scheme should gather coverage data. This defaults to false
|
||||
- [ ] **commandLineArguments**: **[String:Bool]** - a dictionary from the argument name (`String`) to if it is enabled (`Bool`). These arguments will be added to the Test, Profile and Run scheme actions
|
||||
- [ ] **environmentVariables**: **[[Environment Variable](#environment-variable)]** or **[String:String]** - environment variables for Run, Test and Profile scheme actions. When passing a dictionary, every key-value entry maps to a corresponding variable that is enabled.
|
||||
@ -578,7 +578,12 @@ A multiline script can be written using the various YAML multiline methods, for
|
||||
### Test Action
|
||||
|
||||
- [ ] **gatherCoverageData**: **Bool** - a boolean that indicates if this scheme should gather coverage data. This defaults to false
|
||||
- [ ] **targets**: **[String]** - a list of targets to test
|
||||
- [ ] **targets**: **[[Test Target](#test-target)]** - a list of targets to test. Each entry can either be a simple string, or a [Test Target](#test-target)
|
||||
|
||||
#### Test Target
|
||||
- [x] **name**: **String** - The name of the target
|
||||
- [ ] **parallelizable**: **Bool** - Whether to run tests in parallel. Defaults to false
|
||||
- [ ] **randomExecutionOrder**: **Bool** - Whether to run tests in a random order. Defaults to false
|
||||
|
||||
### Archive Action
|
||||
|
||||
|
@ -89,15 +89,40 @@ public struct Scheme: Equatable {
|
||||
public var config: String?
|
||||
public var gatherCoverageData: Bool
|
||||
public var commandLineArguments: [String: Bool]
|
||||
public var targets: [String]
|
||||
public var targets: [TestTarget]
|
||||
public var preActions: [ExecutionAction]
|
||||
public var postActions: [ExecutionAction]
|
||||
public var environmentVariables: [XCScheme.EnvironmentVariable]
|
||||
|
||||
public struct TestTarget: Equatable, ExpressibleByStringLiteral {
|
||||
public let name: String
|
||||
public var randomExecutionOrder: Bool
|
||||
public var parallelizable: Bool
|
||||
|
||||
public init(
|
||||
name: String,
|
||||
randomExecutionOrder: Bool = false,
|
||||
parallelizable: Bool = false
|
||||
) {
|
||||
self.name = name
|
||||
self.randomExecutionOrder = randomExecutionOrder
|
||||
self.parallelizable = parallelizable
|
||||
}
|
||||
|
||||
public init(stringLiteral value: String) {
|
||||
name = value
|
||||
randomExecutionOrder = false
|
||||
parallelizable = false
|
||||
}
|
||||
}
|
||||
|
||||
public init(
|
||||
config: String,
|
||||
gatherCoverageData: Bool = false,
|
||||
randomExecutionOrder: Bool = false,
|
||||
parallelizable: Bool = false,
|
||||
commandLineArguments: [String: Bool] = [:],
|
||||
targets: [String] = [],
|
||||
targets: [TestTarget] = [],
|
||||
preActions: [ExecutionAction] = [],
|
||||
postActions: [ExecutionAction] = [],
|
||||
environmentVariables: [XCScheme.EnvironmentVariable] = []
|
||||
@ -210,13 +235,34 @@ extension Scheme.Test: JSONObjectConvertible {
|
||||
config = jsonDictionary.json(atKeyPath: "config")
|
||||
gatherCoverageData = jsonDictionary.json(atKeyPath: "gatherCoverageData") ?? false
|
||||
commandLineArguments = jsonDictionary.json(atKeyPath: "commandLineArguments") ?? [:]
|
||||
targets = jsonDictionary.json(atKeyPath: "targets") ?? []
|
||||
if let targets = jsonDictionary["targets"] as? [Any] {
|
||||
self.targets = try targets.compactMap { target in
|
||||
if let string = target as? String {
|
||||
return TestTarget(name: string)
|
||||
} else if let dictionary = target as? JSONDictionary {
|
||||
return try TestTarget(jsonDictionary: dictionary)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
targets = []
|
||||
}
|
||||
preActions = jsonDictionary.json(atKeyPath: "preActions") ?? []
|
||||
postActions = jsonDictionary.json(atKeyPath: "postActions") ?? []
|
||||
environmentVariables = try XCScheme.EnvironmentVariable.parseAll(jsonDictionary: jsonDictionary)
|
||||
}
|
||||
}
|
||||
|
||||
extension Scheme.Test.TestTarget: JSONObjectConvertible {
|
||||
|
||||
public init(jsonDictionary: JSONDictionary) throws {
|
||||
name = try jsonDictionary.json(atKeyPath: "name")
|
||||
randomExecutionOrder = jsonDictionary.json(atKeyPath: "randomExecutionOrder") ?? false
|
||||
parallelizable = jsonDictionary.json(atKeyPath: "parallelizable") ?? false
|
||||
}
|
||||
}
|
||||
|
||||
extension Scheme.Profile: JSONObjectConvertible {
|
||||
|
||||
public init(jsonDictionary: JSONDictionary) throws {
|
||||
|
@ -110,8 +110,8 @@ extension Project {
|
||||
}
|
||||
|
||||
for testTarget in scheme.testTargets {
|
||||
if getTarget(testTarget) == nil {
|
||||
errors.append(.invalidTargetSchemeTest(target: target.name, testTarget: testTarget))
|
||||
if getTarget(testTarget.name) == nil {
|
||||
errors.append(.invalidTargetSchemeTest(target: target.name, testTarget: testTarget.name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import JSONUtilities
|
||||
import xcodeproj
|
||||
|
||||
public struct TargetScheme: Equatable {
|
||||
public var testTargets: [String]
|
||||
public var testTargets: [Scheme.Test.TestTarget]
|
||||
public var configVariants: [String]
|
||||
public var gatherCoverageData: Bool
|
||||
public var commandLineArguments: [String: Bool]
|
||||
@ -12,7 +12,7 @@ public struct TargetScheme: Equatable {
|
||||
public var postActions: [Scheme.ExecutionAction]
|
||||
|
||||
public init(
|
||||
testTargets: [String] = [],
|
||||
testTargets: [Scheme.Test.TestTarget] = [],
|
||||
configVariants: [String] = [],
|
||||
gatherCoverageData: Bool = false,
|
||||
commandLineArguments: [String: Bool] = [:],
|
||||
@ -33,7 +33,19 @@ public struct TargetScheme: Equatable {
|
||||
extension TargetScheme: JSONObjectConvertible {
|
||||
|
||||
public init(jsonDictionary: JSONDictionary) throws {
|
||||
testTargets = jsonDictionary.json(atKeyPath: "testTargets") ?? []
|
||||
if let targets = jsonDictionary["testTargets"] as? [Any] {
|
||||
self.testTargets = try targets.compactMap { target in
|
||||
if let string = target as? String {
|
||||
return .init(name: string)
|
||||
} else if let dictionary = target as? JSONDictionary {
|
||||
return try .init(jsonDictionary: dictionary)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
testTargets = []
|
||||
}
|
||||
configVariants = jsonDictionary.json(atKeyPath: "configVariants") ?? []
|
||||
gatherCoverageData = jsonDictionary.json(atKeyPath: "gatherCoverageData") ?? false
|
||||
commandLineArguments = jsonDictionary.json(atKeyPath: "commandLineArguments") ?? [:]
|
||||
|
@ -95,9 +95,9 @@ public class SchemeGenerator {
|
||||
return XCScheme.BuildAction.Entry(buildableReference: buildableReference, buildFor: buildTarget.buildTypes)
|
||||
}
|
||||
|
||||
let testTargetNames = scheme.test?.targets ?? []
|
||||
let testBuildTargets = testTargetNames.map {
|
||||
Scheme.BuildTarget(target: $0, buildTypes: BuildType.testOnly)
|
||||
let testTargets = scheme.test?.targets ?? []
|
||||
let testBuildTargets = testTargets.map {
|
||||
Scheme.BuildTarget(target: $0.name, buildTypes: BuildType.testOnly)
|
||||
}
|
||||
|
||||
let testBuildTargetEntries = testBuildTargets.map(getBuildEntry)
|
||||
@ -128,8 +128,11 @@ public class SchemeGenerator {
|
||||
buildImplicitDependencies: scheme.build.buildImplicitDependencies
|
||||
)
|
||||
|
||||
let testables = testBuildTargetEntries.map {
|
||||
XCScheme.TestableReference(skipped: false, buildableReference: $0.buildableReference)
|
||||
let testables = zip(testTargets, testBuildTargetEntries).map { testTarget, testBuilEntries in
|
||||
XCScheme.TestableReference(skipped: false,
|
||||
parallelizable: testTarget.parallelizable,
|
||||
randomExecutionOrdering: testTarget.randomExecutionOrder,
|
||||
buildableReference: testBuilEntries.buildableReference)
|
||||
}
|
||||
|
||||
let testCommandLineArgs = scheme.test.map { XCScheme.CommandLineArguments($0.commandLineArguments) }
|
||||
|
@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1000"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "NT_BEB0891E36797FE2214A0A9D516D408D"
|
||||
BuildableName = "App_iOS.app"
|
||||
BlueprintName = "App_iOS"
|
||||
ReferencedContainer = "container:Project.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Production Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
codeCoverageEnabled = "YES"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "NT_D4BAEEEC88124103C8DFF41FCE206DCE"
|
||||
BuildableName = "App_iOS_UITests.xctest"
|
||||
BlueprintName = "App_iOS_UITests"
|
||||
ReferencedContainer = "container:Project.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
<TestableReference
|
||||
skipped = "NO"
|
||||
parallelizable = "YES"
|
||||
testExecutionOrdering = "random">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "NT_193BAF154270D1C21E269EDF2A1BD3F6"
|
||||
BuildableName = "App_iOS_Tests.xctest"
|
||||
BlueprintName = "App_iOS_Tests"
|
||||
ReferencedContainer = "container:Project.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "NT_BEB0891E36797FE2214A0A9D516D408D"
|
||||
BuildableName = "App_iOS.app"
|
||||
BlueprintName = "App_iOS"
|
||||
ReferencedContainer = "container:Project.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<CommandLineArguments>
|
||||
</CommandLineArguments>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Production Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "NT_BEB0891E36797FE2214A0A9D516D408D"
|
||||
BuildableName = "App_iOS.app"
|
||||
BlueprintName = "App_iOS"
|
||||
ReferencedContainer = "container:Project.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Production Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "NT_BEB0891E36797FE2214A0A9D516D408D"
|
||||
BuildableName = "App_iOS.app"
|
||||
BlueprintName = "App_iOS"
|
||||
ReferencedContainer = "container:Project.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Production Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Production Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
@ -44,6 +44,7 @@
|
||||
buildConfiguration = "Production Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
codeCoverageEnabled = "YES"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -56,6 +57,8 @@
|
||||
ReferencedContainer = "container:Project.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<CommandLineArguments>
|
||||
</CommandLineArguments>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
|
@ -217,6 +217,19 @@ schemes:
|
||||
commandLineArguments:
|
||||
argument: YES
|
||||
argument.with.dot: YES
|
||||
test:
|
||||
gatherCoverageData: true
|
||||
App_Scheme:
|
||||
build:
|
||||
targets:
|
||||
App_iOS: all
|
||||
test:
|
||||
gatherCoverageData: true
|
||||
targets:
|
||||
- App_iOS_UITests
|
||||
- name: App_iOS_Tests
|
||||
parallelizable: true
|
||||
randomExecutionOrder: true
|
||||
targetTemplates:
|
||||
MyTemplate:
|
||||
scheme: {}
|
||||
|
@ -253,7 +253,7 @@ class SpecLoadingTests: XCTestCase {
|
||||
$0.it("parses target schemes") {
|
||||
var targetDictionary = validTarget
|
||||
targetDictionary["scheme"] = [
|
||||
"testTargets": ["t1", "t2"],
|
||||
"testTargets": ["t1", ["name": "t2"]],
|
||||
"configVariants": ["dev", "app-store"],
|
||||
"commandLineArguments": [
|
||||
"ENV1": true,
|
||||
@ -312,6 +312,18 @@ class SpecLoadingTests: XCTestCase {
|
||||
],
|
||||
],
|
||||
],
|
||||
"test": [
|
||||
"config": "debug",
|
||||
"targets": [
|
||||
"Target1",
|
||||
[
|
||||
"name": "Target2",
|
||||
"parallelizable": true,
|
||||
"randomExecutionOrder": true,
|
||||
],
|
||||
],
|
||||
"gatherCoverageData": true,
|
||||
]
|
||||
]
|
||||
let scheme = try Scheme(name: "Scheme", jsonDictionary: schemeDictionary)
|
||||
let expectedTargets: [Scheme.BuildTarget] = [
|
||||
@ -330,6 +342,16 @@ class SpecLoadingTests: XCTestCase {
|
||||
|
||||
try expect(scheme.build.parallelizeBuild) == false
|
||||
try expect(scheme.build.buildImplicitDependencies) == false
|
||||
|
||||
let expectedTest = Scheme.Test(config: "debug",
|
||||
gatherCoverageData: true,
|
||||
targets: [
|
||||
"Target1",
|
||||
Scheme.Test.TestTarget(name: "Target2",
|
||||
randomExecutionOrder: true,
|
||||
parallelizable: true)
|
||||
])
|
||||
try expect(scheme.test) == expectedTest
|
||||
}
|
||||
|
||||
$0.it("parses schemes variables") {
|
||||
|
Loading…
Reference in New Issue
Block a user