<div dir="ltr">In case anyone interested missed it, John Holdsworth mentions another approach in a comment on <a href="https://bugs.swift.org/browse/SR-710">https://bugs.swift.org/browse/SR-710</a>: using runtime metadata to find a list of tests. The linked project contains an example. It:<br><br>1. Specifies a test method regex: <a href="https://github.com/johnno1962/TestRunner/blob/201bd04af14fdebf1a7fa2ae0a419fc59d6266ed/TestRunner/AppDelegate.swift#L69">https://github.com/johnno1962/TestRunner/blob/201bd04af14fdebf1a7fa2ae0a419fc59d6266ed/TestRunner/AppDelegate.swift#L69</a><br>2. In Swift, the project exposes metadata information for Swift objects: <a href="https://github.com/johnno1962/TestRunner/blob/201bd04af14fdebf1a7fa2ae0a419fc59d6266ed/TestRunner/TestRunner.swift#L52">https://github.com/johnno1962/TestRunner/blob/201bd04af14fdebf1a7fa2ae0a419fc59d6266ed/TestRunner/TestRunner.swift#L52</a><div>3. Uses an UnsafeMutablePointer&lt;ClassMetadataSwift&gt; to get a reference to the methods defined on an instance: <a href="https://github.com/johnno1962/TestRunner/blob/201bd04af14fdebf1a7fa2ae0a419fc59d6266ed/TestRunner/TestRunner.swift#L97">https://github.com/johnno1962/TestRunner/blob/201bd04af14fdebf1a7fa2ae0a419fc59d6266ed/TestRunner/TestRunner.swift#L97</a><br><br>I assume this approach won&#39;t be acceptable to some because it relies on private information about Swift objects, but I don&#39;t know for sure. Please chime in if this approach seems reasonable to you!<br><br>Based on the assumption that we can&#39;t use metadata, however, I&#39;m going to try to begin working on approaches #2 or #3, which I mentioned in my original email. I think the preliminary work is the same (like moving SourceKit::FuncDeclEntityInfo.IsTestCandidate to libIDE), so I&#39;ll hold off on making a hard decision between #2 and #3 until necessary.<br><br></div><div>- Brian Gesiak</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 4, 2016 at 12:23 AM, Daniel Dunbar <span dir="ltr">&lt;<a href="mailto:daniel_dunbar@apple.com" target="_blank">daniel_dunbar@apple.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
&gt; On Apr 3, 2016, at 3:36 PM, Dmitri Gribenko &lt;<a href="mailto:gribozavr@gmail.com">gribozavr@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt; On Sun, Apr 3, 2016 at 2:11 PM, Brian Gesiak &lt;<a href="mailto:modocache@gmail.com">modocache@gmail.com</a>&gt; wrote:<br>
&gt;&gt; I think #2 is the best option. It’s less work than both #1 and #3. I believe<br>
&gt;&gt; logic like IsTestCandidate belongs in libIDE anyway—SourceKit should stick<br>
&gt;&gt; to XPC and asynchronous communication with libIDE.<br>
&gt;<br>
&gt; I like #3 better (an option to swiftc), because that would decouple<br>
&gt; the test discovery tool from the Swift compiler.  That would allow you<br>
&gt; to use the discovery tool with different compilers.  And, because we<br>
&gt; would avoid statically linking libIDE, it would mean one less copy of<br>
&gt; LLVM, Clang and Swift in the toolchain.<br>
<br>
</span>Ultimately my opinion is that it is likely that the package manager will want an API interface to Swift in any case. I personally would rather we simply plan on that.<br>
<br>
I also would like to avoid duplicating anything in the toolchain, but think that should be done by moving the driver to sitting on top of a shared library.<br>
<span class=""><br>
&gt;&gt; Not being an expert in many of these components, I have several questions:<br>
&gt;&gt;<br>
&gt;&gt; I’m assuming the reflection API to return a list of instance methods on a<br>
&gt;&gt; XCTestCase subclass is not ready yet, and won’t be for some time. Is this<br>
&gt;&gt; accurate?<br>
&gt;<br>
&gt; I think so.<br>
&gt;<br>
&gt;&gt; I’m assuming that SourceKit is intended to be an asynchronous wrapper over<br>
&gt;&gt; libIDE, and that logic like IsTestCandidate should be moved to libIDE. Is<br>
&gt;&gt; this accurate?<br>
&gt;<br>
&gt; SourceKit has a lot of functionality of its own, but moving this<br>
&gt; particular piece of logic to libIDE sounds reasonable.<br>
&gt;<br>
&gt;&gt; I’m assuming that SourceKit is coupled with XPC, and that it would be more<br>
&gt;&gt; work to port it to Linux than it would be to move its logic to libIDE. Is<br>
&gt;&gt; this accurate?<br>
&gt;<br>
&gt; It is not tightly coupled with XPC, there is a portability layer that<br>
&gt; you could implement for Linux.  You would need to decide on an IPC<br>
&gt; mechanism and serialization format though.<br>
<br>
</span>For our purposes, I don&#39;t think we need IPC. I think a direct (C) library interface would be fine. Clients can implement the IPC/XPC if they need it.<br>
<span class=""><br>
&gt;&gt; If you have thoughts/feedback, please reply to this email or comment on<br>
&gt;&gt; SR-710. Your input would be greatly appreciated!!<br>
&gt;<br>
&gt; I&#39;m wondering how feasible is it to change the XCTest API to<br>
&gt; accommodate better the Swift language that we have, rather than trying<br>
&gt; to add custom tooling to make the existing API work.  Adding magic<br>
&gt; tooling that adds behavior not present in the language seems unnatural<br>
&gt; to me.<br>
<br>
</span>I agree with you that it is unnatural, but I think this ship has sailed for XCTest, we have a need to support the existing API in a cross platform manner.<br>
<br>
My personal preference is that eventually we would build features like this on top of general support for attributes (a la Java/Python/C#).<br>
<span class=""><br>
&gt; Compare with StdlibUnittest -- by using an API to build tests we get<br>
&gt; the following advantages:<br>
&gt;<br>
&gt; - We completely avoid having the issue of test discovery, executing<br>
&gt; the code discovers the tests.  No reflection needed!<br>
<br>
</span>While I think StdlibUnittest is neat, I also believe that there are very good reasons for supporting test discovery in a test suite. I have used these features in other suites to great avail to create (bidirectional, sometimes) lit bridge adaptors between various test frameworks (Python unittest, googletest, XCTest).<br>
<br>
In an IDE context, it is also very useful to be able to perform test discovery independent of test execution.<br>
<br>
As one other example, I&#39;ve used lit with suites with hundreds of thousands of tests... it would be unfortunate to have to dynamically discover all of those tests when the user is just trying to run a single one.<br>
<span class=""><br>
&gt; - We can add attributes to tests (for example, skip, xfail).  In the<br>
&gt; current XCTest API this would require adding some kind of user-defined<br>
&gt; attributes, which is another language which is a long way from being<br>
&gt; designed and implemented.<br>
<br>
</span>This isn&#39;t necessarily the case, XCTest could in theory provide explicit APIs to do these things as part of test execution. I agree attributes are a better fit in the current model.<br>
<span class=""><br>
&gt; - We can define data-parameterized tests.<br>
<br>
&gt; - Tests can be dynamically synthesized by control flow.  In the<br>
&gt; current XCTest API, dynamically generating tests would mean<br>
&gt; dynamically generating methods, which is even more far off than<br>
&gt; read-only method reflection.<br>
<br>
</span>FWIW, XCTest has some support for doing these kinds of things, they just don&#39;t take the form of the pattern-matched methods.<br>
<span class="HOEnZb"><font color="#888888"><br>
 - Daniel<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
&gt;<br>
&gt; Dmitri<br>
&gt;<br>
&gt; --<br>
&gt; main(i,j){for(i=2;;i++){for(j=2;j&lt;i;j++){if(!(i%j)){j=0;break;}}if<br>
&gt; (j){printf(&quot;%d\n&quot;,i);}}} /*Dmitri Gribenko &lt;<a href="mailto:gribozavr@gmail.com">gribozavr@gmail.com</a>&gt;*/<br>
<br>
</div></div></blockquote></div><br></div>