<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Daniel:</div><div class=""><br class=""></div><div class=""><div class="">It looks like your last reply was referencing the original draft I sent in July, not the 2nd draft I sent 11/10. Pasted below is a 3rd draft, removing the bit about @testable.</div></div><div class=""><br class=""></div><div class="">Regarding your second comment, I had previously removed the stuff about outputting a manifest. I agree with both of your responses.</div><div class=""><br class=""></div>Ankit:<div class=""><br class=""></div><div class=""><blockquote type="cite" class="">This proposal sounds similar to allowing regular modules (lib+exec) inside Tests/ and IMO that is better than just allowing executables and is more general. Right now we error out when some directory doesn't have Tests prefix in Tests/ folder, We can just allow that and use same rule of main.swift to distinguish between lib and exec.</blockquote></div><div class=""><br class=""></div><div class="">Expanding the change to lib+exec seems reasonable. However, my understanding is that the motivation for supporting lib is a bit different. At the moment my proposal is almost entirely focused on motivation. If the change gets made, I'm happy to drop the proposal, but I just want to be clear about the use case.</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">George</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><h1 id="test-executables" style="padding-bottom: 0.3em; line-height: 1.2; border-bottom-width: 1px; border-bottom-style: solid; border-color: rgba(0, 0, 0, 0.180392); font-weight: normal; color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Test Executables</h1><ul style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class=""><li class="">Proposal: <a href="NNNN-filename.md" style="color: rgb(64, 128, 208); text-decoration: none;" class="">SE-NNNN</a></li><li class="">Author: <a href="https://github.com/gwk" style="color: rgb(64, 128, 208); text-decoration: none;" class="">George King</a></li><li class="">Status: <strong class="">Awaiting review</strong> / <strong class="">DRAFT 3</strong></li><li class="">Review manager: TBD</li></ul><h2 id="introduction" style="font-weight: normal; color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">Introduction</h2><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">The package manager currently supports testing via XCTest, but does not provide support for other testing methodologies. In particular, facilities for building test executables (that is, executables meant strictly for testing and not as an end product) in the Swift Package Manager would make command line testing of Swift packages easier and more robust. We propose to add to the package manager the ability to specify and build test-only executable targets that are distinct from regular executables.</p><h2 id="motivation" style="font-weight: normal; color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">Motivation</h2><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class=""><a href="https://en.wikipedia.org/wiki/Integration_testing" style="color: rgb(64, 128, 208); text-decoration: none;" class="">Integration testing</a> is, broadly speaking, the practice of testing multiple software components such as functions and classes (which may be "unit tested" individually) in aggregate. Integration tests can reveal bugs arising from interactions between components, can validate the intended usage patterns for individual components, and serve as references for that intended usage.</p><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">XCTest offers <a href="https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/chapters/03-testing_basics.html#//apple_ref/doc/uid/TP40014132-CH3-SW8" style="color: rgb(64, 128, 208); text-decoration: none;" class="">facilities</a> for unit testing, performance testing, and GUI testing, but not for testing the basic IO behavior of a process. To be clear, this proposal does not address XCTest at all; while adding whole process, IO oriented APIs to XCTest sounds desirable, it is a larger project and out of scope for this proposal.</p><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">Instead, this proposal simply asks for the ability to build executables specifically for testing, rather than for public usage. The intended use case is execution via an external test harness, or from within an XCTest case via NSTask/Process.</p><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">Consider the existing features of swiftpm as two orthogonal axes:</p><ul style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class=""><li class="">Build, Test</li><li class="">Library, Executable</li></ul><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">Of the four combinations, only "Test Executable" is missing.</p><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">Currently, test executables can simply be placed in the <code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">Sources</code>, where they are compiled as regular executable targets. Distinguishing them as test executables would be helpful for several reasons:</p><ul style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class=""><li class="">Test executables would only be built by <code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">swift test</code>, not <code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">swift build</code>.</li><li class="">Putting all test code in the <code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">Tests</code> directory will prevent test executables from being exposed to library consumers, and clarifies developer intent.</li><li class="">For simple projects that produce a single library module, adding a test executable will no longer necessitate moving the library code from <code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">Sources/</code> to <code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">Sources/[Module]</code> to allow for the second target.</li></ul><h2 id="proposed-solution" style="font-weight: normal; color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">Proposed solution</h2><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class=""><code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">swift test</code> should distinguish between unit test directories and executable directories, just as <code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">swift build</code> distinguishes between libary and executable directories.</p><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">The <code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">swift test</code> command should, upon encountering a test executable directory, build the executable.</p><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">If the test executable build fails, <code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">swift test</code> should report a test failure and return a nonzero exit code. An external test harness can then run the test executables as it sees fit. Note that for an XCTest case to invoke the test executable, test executables would need to be built prior to running test cases.</p><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">Future improvements could include invoking an external test command specified in <code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">Package.swift</code> upon successful build.</p><h2 id="detailed-design" style="font-weight: normal; color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">Detailed design</h2><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">TODO.</p><h2 id="impact-on-existing-code" style="font-weight: normal; color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">Impact on existing code</h2><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">None; <code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">swift test</code> currently appears to ignore subdirectories in <code style="font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback'; line-height: 19px; color: rgb(163, 21, 21);" class="">Tests</code> that do not contain XCTest-based unit tests.</p><h2 id="alternatives-considered" style="font-weight: normal; color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">Alternatives considered</h2><h3 id="no-action" style="font-weight: normal; color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">No action</h3><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">See the list of problems with treating test executables as regular targets in the "Motivation" section above.</p><h3 id="complete-integration-testing-with-xctest" style="font-weight: normal; color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">Complete integration testing with XCTest</h3><p style="color: rgb(30, 30, 30); font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback'; font-size: 14px; font-variant-ligatures: normal; line-height: 22px; orphans: 2; widows: 2;" class="">This would be a much larger undertaking, and it seems likely that such a solution would necessitate the essentials of this proposal anyway.</p></div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>