<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><div><span style="background-color: rgba(255, 255, 255, 0);">Just to share my feelings and ideas.</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">It seems to me it would be better addressed by code review. Among other things it would start the conversation about what should be made public, what should not, and why.</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">On the automated part, there could be tools detecting changes to the public APIs (and providing diff) to trigger a review or something.</span></div><div><br></div><div><br></div>Pierre</div><div><br>Le 13 déc. 2016 à 16:57, Benjamin Spratling via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; a écrit&nbsp;:<br><br></div><blockquote type="cite"><div><meta http-equiv="content-type" content="text/html; charset=utf-8"><div>Howdy,</div><div><br></div><div>If my immediate goal were to verify private member values at intermediate steps in some process, which is the concept under consideration in the article you provided, I could access their values with a Mirror.</div><div><br></div><div>That's not my immediate goal. &nbsp;My immediate goal is to falsify that the property is private. &nbsp;The logic in the article asserts that a member is private, then asserts that because the member is private we do not need to test it. &nbsp;But it fails to provide an automated test that the member is indeed private and remains so. &nbsp;To accomplish that goal without an automated unit test is painstakingly tedious for a human.</div><div><br></div><div>And as to whether the logic in the article is correct, assuming its assumptions are true, it is still only one kind of testing. &nbsp;Depending on the field it might be called "interface" or "black box" testing, and they rightly call that out. &nbsp;But it would not be considered to be the only kind of testing which needs to be done.</div><div><br><div>-Ben<div><br>Sent from my iPhone.</div></div></div><div><br>On Dec 13, 2016, at 1:35 AM, Jean-Daniel &lt;<a href="mailto:mailing@xenonium.com">mailing@xenonium.com</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8">An interesting reading about testing private members:<div class=""><br class=""></div><div class=""><a href="https://cocoacasts.com/how-to-unit-test-private-methods-in-swift/" class="">https://cocoacasts.com/how-to-unit-test-private-methods-in-swift/</a></div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">Le 12 déc. 2016 à 06:10, Derrick Ho via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="Apple-interchange-newline"><div class="">It bugs me as well that we can not test private components using XCTest.  Objective-c never had this problem since privacy doesn't exist.  I would like to see a version of XCTest that allows us to test every component.<br class=""><br class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Mon, Dec 12, 2016 at 12:02 AM Benjamin Spratling via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Howdy,<br class="gmail_msg">
&nbsp; &nbsp; &nbsp; &nbsp; I’d like to see how much interest there is for adding these to the XCTest module.&nbsp; If I have missed some pro or con, or missed a technical point, your feedback is welcome before I go to the lengths to draw up a formal proposal.<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
There are several features of Swift which cannot be effectively automated-tested.<br class="gmail_msg">
For instance, when a type or one of its members is private or file private, an outside test suite cannot access it, and the information that the type is private is not included in a Mirror.&nbsp; There are similar concerns for testability with internal, and public access levels.&nbsp; Tests can be written ensuring these access levels are &gt;= some level, but not == or &lt; some level.&nbsp; In other words the very usefulness of these features cannot be tested.<br class="gmail_msg">
<br class="gmail_msg">
Other attributes to be tested in this way are:<br class="gmail_msg">
<br class="gmail_msg">
- Mutability of a member.&nbsp; No automated test can be written which verifies that a function cannot be called on a let struct, or that a property cannot be set at a specific access level.<br class="gmail_msg">
<br class="gmail_msg">
- That a stored property is weak or unowned.<br class="gmail_msg">
<br class="gmail_msg">
- That a class or class member is “final”<br class="gmail_msg">
<br class="gmail_msg">
These are concepts which need to be unit-tested to ensure good design is not broken, but do not need to be included in a release build, so including them in the XCTest framework seems like an appropriate destination.<br class="gmail_msg">
Moreover, the information for all of these features exists in the .swiftmodule files, which are included in test builds, but sometimes stripped for release.<br class="gmail_msg">
<br class="gmail_msg">
Examples:<br class="gmail_msg">
Since these features inherently have to do with testing features which cannot be stated in compiled code, I recommend specifying names with Strings.&nbsp; Here are some examples of what I would like to write in my test code:<br class="gmail_msg">
<br class="gmail_msg">
XCTAssertEqual( Module(named:”SingMusicLayout”)?.type(named:”NoteSetter”)?.property(named:”session”)?.accessLevel, .private)<br class="gmail_msg">
<br class="gmail_msg">
XCTAssertEqual( Module(named:”SingMusicLayout”)?.type(named:”ScaleLayout”)?.method(named:”baselineOffset(for:PitchInterval)-&gt;CGFloat”)?.mutable, false)<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
Alternatives:<br class="gmail_msg">
1.&nbsp; &nbsp; &nbsp; Building an independent .swiftmodule parser in a single Swift module, which can be included in test builds.<br class="gmail_msg">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + Can be distributed independently from Swift sources, requiring 0 buy-in from Swift community<br class="gmail_msg">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + requires a single additional module for the test.<br class="gmail_msg">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - Depends on ever-changing binary interface.<br class="gmail_msg">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Intractable, not DRY<br class="gmail_msg">
<br class="gmail_msg">
2.&nbsp; &nbsp; &nbsp; Use existing sourcekitd.<br class="gmail_msg">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + harnesses changes in the compiler’s source code with SourceKit<br class="gmail_msg">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - cannot be run in a test suite without extensive work by user to configure bundles explicitly.<br class="gmail_msg">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Exceptionally poor user experience<br class="gmail_msg">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : sourcekitd XPC architecture only works on macOS<br class="gmail_msg">
<br class="gmail_msg">
3.&nbsp; &nbsp; &nbsp; Use a standalone tool for tests<br class="gmail_msg">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + harnesses changes in the compiler’s source code with SourceKit<br class="gmail_msg">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + no installation in user’s source code necessary<br class="gmail_msg">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : cannot be effectively run by SPM test infrastructure<br class="gmail_msg">
<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></blockquote></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>