Exclude test classes from code coverage

I am trying to use code coverage in Xcode to view the unit test coverage stats for my app.

In my scheme I have enabled code coverage, but I had to also select "Show Test Bundles" to see the code coverage reports.

The reports are showing, but for some reason the test classes themselves are also included. I only want to see code coverage for the classes that are being tested.

Is there any way to remove the test classes from this report?

Thanks

Deselecting the Show Test Bundles checkbox is the way to remove the test classes from the code coverage report. Until you figure out why the code coverage reports appear only when the Show Test Bundles checkbox is selected, you can click the disclosure triangle next to the test target to hide the test classes in the report.

Thanks, I had a feeling it might be related to "Show Test Bundles", but I wasn't able to find any more information or documentation about it. Unfortunately clicking the disclosure triangle next to the test target won't work since everything, both tests classes and classes-under-test, are inside of the test.xctest target and clicking the triangle will hide everything!

It looks like the application classes being tested are members of the test target. The coverage report should have a listing for your application target, where you can examine the coverage for each class being tested. If you select the Show Test Bundles checkbox, there will be another entry for the test target. The disclosure triangles are actually helpful.


If you select one of your application class files (The .m file if you're using Objective-C) in the project navigator, the file inspector will show the file's target memberships. Deselect the test target checkbox.


Removing the test target membership may now screw up your unit tests. In your test class files, you'll need to import your application module so the test classes can access your application's classes. In Swift use the @testable import statement.


@testable import AppName


In Objective-C use the import statement.


You may also need to select your test target in the project editor and set your application as the host application.

Edit: 'Looks like 'szymczyk' and I were writing our response at the same time. Anyhow, I think we're saying the same thing.


It sounds like you have your project configured like I used to do things. For example, having the actual items to test being members of both targets (app target and the testing target). In that case, there is no way to generate a coverage report to exclude the test suites. That's because the app code is being included in the test bundle and thus unchecking 'Show Test Bundles' will hide everything.


The fix is to have your app code only reside in the app target and your test suites still only residing in the test bundle target. Then, use the @testable import clause in your unit test suites.


For example, I just created a single-view iOS app with unit tests with a project name of 'UnitTests'. I then added a Person.swift class to my 'UnitTests' target (but no the UnitTestsTests target).


Then, added a PersonTests.swift suite to the UnitTestsTests target and added this line after the import of XCTest:


@testable import UnitTests


After turning on code coverage and doing a run, my coverage shows this (when 'Show Test Bundles' is checked):


UnitTestsTests.xctest

* PersonTests.swift

* UnitTestsTests.swift

UnitTests.app

* Person.swift

* ViewController.swift

* AppDelegate.swift


Coverage data for 'Person' was filled in correctly. Unchecking the 'Show Test Bundles' checkbox hides the first grouping as expected. The coverage for Person.swift is still there (since it's only listed in the app bundle).

Thanks, that clears a lot up. After more research I think the issue may actually be that my project is a static library, and although I did not explicitly add my classes to the test target, I did not have a host application for the unit test target. I added a host application for my target and linked my library against it. Now, when I run my tests and look at the code coverage, I do see both the test bundle and now I see the app bundle as well. However, inside the app bundle I only see main.m and appdelegate.m. I am not referencing my library directly inside the app, but just linking the library to it, thinking this would be enough.

Sorry if this is a little off topic but any help would be useful for me! ... I'm assuming running tests hosted in this app will only show up in code coverage if the tests are testing the interaction between the host app and the library?

How can I see code coverage of tests inside a library?

Thanks for the answer rsharp, very helpful, although it turns out this was not my issue exactly (see my answer above). I believe the root issue is not that my classes were part of the test target, it was that my tests are not hosted in an application, because they are testing a static library. Do you know, is it possible to gather code coverage data from a library?

I've never unit tested a library so I can't tell you how to see the code coverage of a library's unit tests.

ok thanks for helping anyway!

Yes, it is possible to gather code coverage data from a library. Targets are targets.

Beast's response gave me something else to check. Did you import the name of your library in your unit test classes? I used the term AppName in my example, but AppName refers to what you're testing. In most cases it's an application, but in your case it's a library.

Because the test classes are part of the same project as the library source code, I have only been importing the individual classes under test like so:


#import "ClassUnderTest.h"


into each test class.

It would seem so, but if I do not specify a host application, only the test bundle shows up in the 'code coverage' tab, not the library target.


This can be also seen in the sample Apple project ("Unit Testing Apps and Frameworks") here: https://developer.apple.com/library/ios/samplecode/UnitTests/Introduction/Intro.html#//apple_ref/doc/uid/DTS40011742


If you run unit tests on the Calculator-iOS target, which is a library target that runs the Calculator-iOS_LogicTests tests, with code coverage enabled, you can see the same behaviour I am getting.


The Coverage tab only shows the Test Bundles (if selected), and inside the Calculator-iOS_LogicTests.xctest bundle you can see coverage stats of both test classes and classes under test.


This is the same behaviour I am seeing. If you have any ideas how to show only the classes under test here, please let me know, thanks a bunch!


Edit: I have asked this as a separate question over here: https://forums.developer.apple.com/message/175767

Ther is no need for host application.
Just open project. Select your Test target on the left. Go to "Build Settings". Make sure among "Basic", "Customized", "All" options, option "All" is selected. Search for option CLANG_ENABLE_CODE_COVERAGE and set the value to "No".

Exclude test classes from code coverage
 
 
Q