Skip to content

Commit 70a5a38

Browse files
Merge pull request jonreid#1 from designatednerd/master
Lcov 1.11 + CocoaPod
2 parents 1c1ddd2 + ee8928d commit 70a5a38

File tree

10 files changed

+1092
-112
lines changed

10 files changed

+1092
-112
lines changed

README.md

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,75 @@
11
![XcodeCoverage](http://qualitycoding.org/jrwp/wp-content/uploads/2014/03/XcodeCoverage.png)
22

3-
These scripts provide a simple way to generate HTML reports of the code coverage
4-
of your Xcode project.
3+
These scripts provide a simple way to generate HTML reports of the code coverage of your Xcode project.
54

65

7-
Installation
8-
============
6+
Xcode Project Setup
7+
===================
8+
9+
Before you get started, there are a couple of steps you will need to take to prepare your project:
10+
11+
1. Depending on your version of Xcode, you may need to get Xcode's coverage instrumentation by going to Xcode > Preferences, into Downloads, and installing Command Line Tools. If you do not see this as an option in the Downloads section, the tools should already be installed.
12+
4. In your Xcode project, enable these two build settings at the project level for your Debug configuration only:
13+
* Instrument Program Flow
14+
* Generate Test Coverage Files
15+
916

10-
1. Fork this repository; you're probably going to want to make your own
11-
modifications.
17+
Installation: Standard
18+
======================
19+
20+
1. Fork this repository; you're probably going to want to make your own modifications.
1221
2. Place the XcodeCoverage folder in the same folder as your Xcode project.
13-
3. Depending on your version of Xcode, you may need to get Xcode's coverage
14-
instrumentation by going to Xcode Preferences, into Downloads, and installing
15-
Command Line Tools.
16-
4. In your Xcode project, enable these two build settings at the project level
17-
for your Debug configuration only:
18-
* Instrument Program Flow
19-
* Generate Test Coverage Files
20-
5. In your main target, add a Run Script build phase to execute
21-
``XcodeCoverage/exportenv.sh``
22+
5. In your main target, add a Run Script build phase to execute `XcodeCoverage/exportenv.sh`
23+
24+
A few people have been tripped up by the last step: Make sure you add the script to your main target (your app or library), not your test target.
25+
26+
27+
Installation: CocoaPods
28+
=======================
2229

23-
A few people have been tripped up by the last step: Make sure you add the
24-
script to your main target (your app or library), not your test target.
30+
A [CocoaPod](http://cocoapods.org/) has been added for convenient use in simple projects. There are a couple of things you should be aware of if you are using the CocoaPod instead of the standard method:
31+
32+
- There will be no actual files added to your project. Files are only added through `preserve_paths`, so they will be available in your `Pods/XcodeCoverage` path, but you will not see them in Xcode, and they will not be compiled by Xcode.
33+
- You will not be able to modify the scripts without those modifications being potentially overwritten by CocoaPods.
34+
35+
If those caveats are deal-breakers, please use the standard installation method above.
36+
37+
The steps to install via CocoaPods:
38+
39+
1. Add `pod 'XcodeCoverage', '~>1.0'` (or whatever [version specification](http://guides.cocoapods.org/using/the-podfile.html#specifying-pod-versions) you desire) to your Podfile.
40+
2. Run `pod install`. This will download the necessary files.
41+
3. In your main target, add a Run Script build phase to execute
42+
`Pods/XcodeCoverage/exportenv.sh`.
43+
44+
Again, make sure you add the script to your main target (your app or library), not your test target.
2545

2646

2747
Execution
2848
=========
2949

30-
1. Run your unit tests
50+
Immediately after installation, run your application at least once to generate the `env.sh` file, which will be placed at the same level as your `.xcodeproj` folder. This file should *not* be checked into version control, since it contains paths local to your machine.
51+
52+
Once that task has been completed, the process is very simple:
53+
54+
1. Run your unit tests.
3155
2. In Terminal, execute `getcov` in your project's XcodeCoverage folder.
3256

33-
If you make changes to your test code without changing the production code and
34-
want a clean slate, use the ``cleancov`` script.
57+
If you make changes to your test code without changing the production code and want a clean slate, use the `cleancov` script.
3558

36-
If you make changes to your production code, you should clear out all build
37-
artifacts before measuring code coverage again. "Clean Build Folder" by holding
38-
down the Option key in Xcode's "Product" menu.
59+
If you make changes to your production code, you should clear out all build artifacts before measuring code coverage again. "Clean Build Folder" by holding down the Option key in Xcode's "Product" menu, or by using the ⌥⇧⌘K key combination.
3960

4061
**Optional:** XcodeCoverage can prompt to run code coverage after running unit tests:
4162

4263
* Edit Xcode scheme -> Test -> Post-actions
43-
* Set "Shell" to: ``/bin/bash``
64+
* Set "Shell" to: `/bin/bash`
4465
* Set "Provide build settings from" to your main target
45-
* Set script to:
46-
``source ${SRCROOT}/XcodeCoverage/run_code_coverage_post.sh``
66+
* Set script to: `source ${SRCROOT}/XcodeCoverage/run_code_coverage_post.sh`
4767

4868

4969
Modification
5070
============
5171

52-
There are two places you may want to modify:
72+
There are two places you may want to modify the included files if you are using the standard installation:
5373

54-
1. In envcov.sh, ``LCOV_INFO`` determines the name shown in the report.
55-
2. In getcov, edit ``exclude_data()`` to specify which files to exclude, for
56-
example, third-party libraries.
74+
1. In `envcov.sh`, `LCOV_INFO` determines the name shown in the report.
75+
2. In `getcov`, edit `exclude_data()` to specify which files to exclude, for example, third-party libraries.

XcodeCoverage.podspec

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Pod::Spec.new do |spec|
2+
spec.name = 'XcodeCoverage'
3+
spec.summary = 'Code coverage for Xcode projects'
4+
spec.version = '1.0.0'
5+
spec.platform = :ios
6+
spec.ios.deployment_target = '6.0'
7+
spec.authors = {'Jon Reid' => '[email protected]'}
8+
spec.homepage = 'https://github.com/jonreid/XcodeCoverage'
9+
spec.license = 'MIT'
10+
spec.source = {:git => 'https://github.com/jonreid/XcodeCoverage.git', :tag => "#{spec.version}"}
11+
12+
#these files will be brought into the filesystem, but not added to your .xcodeproj.
13+
spec.preserve_paths = 'cleancov', 'getcov', 'llvm-cov-wrapper.sh', 'envcov.sh', 'lcov-1.11/*', 'exportenv.sh', 'run_code_coverage_post.sh'
14+
15+
spec.requires_arc = true
16+
end

envcov.sh

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,36 @@
55
#
66

77
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
8-
source ${DIR}/env.sh
8+
ENV_DIR="${DIR}"
9+
10+
if [[ $DIR == *Pods/XcodeCoverage* ]]
11+
then
12+
echo "Using Cocoapods!"
13+
cd ..
14+
cd ..
15+
16+
#The env.sh file will be in the project root.
17+
ENV_DIR="$(pwd)"
18+
fi
19+
20+
source ${ENV_DIR}/env.sh
921

1022
# Change the report name if you like:
1123
LCOV_INFO=Coverage.info
1224

1325
XCODECOVERAGE_PATH="${SRCROOT}/XcodeCoverage"
14-
LCOV_PATH="${XCODECOVERAGE_PATH}/lcov-1.10/bin"
26+
27+
if [[ $DIR == *Pods/XcodeCoverage* ]]
28+
then
29+
echo "Using Cocoapods!"
30+
#The current directory will be where XcodeCoverage is living, not in SRCROOT
31+
XCODECOVERAGE_PATH="${DIR}"
32+
fi
33+
34+
LCOV_PATH="${XCODECOVERAGE_PATH}/lcov-1.11/bin"
1535
OBJ_DIR=${OBJECT_FILE_DIR_normal}/${CURRENT_ARCH}
1636

1737
# Fix for the new LLVM-COV that requires gcov to have a -v paramter
1838
LCOV() {
1939
${LCOV_PATH}/lcov "$@" --gcov-tool ${XCODECOVERAGE_PATH}/llvm-cov-wrapper.sh
20-
}
40+
}

exportenv.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
# Source: https://github.com/jonreid/XcodeCoverage
55
#
66

7-
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
7+
DIR="${SRCROOT}"
88
export | egrep '( BUILT_PRODUCTS_DIR)|(CURRENT_ARCH)|(OBJECT_FILE_DIR_normal)|(SRCROOT)|(OBJROOT)' > ${DIR}/env.sh
File renamed without changes.

lcov-1.11/bin/gendesc

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
#!/usr/bin/perl -w
2+
#
3+
# Copyright (c) International Business Machines Corp., 2002
4+
#
5+
# This program is free software; you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation; either version 2 of the License, or (at
8+
# your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful, but
11+
# WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
# General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU General Public License
16+
# along with this program; if not, write to the Free Software
17+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18+
#
19+
#
20+
# gendesc
21+
#
22+
# This script creates a description file as understood by genhtml.
23+
# Input file format:
24+
#
25+
# For each test case:
26+
# <test name><optional whitespace>
27+
# <at least one whitespace character (blank/tab)><test description>
28+
#
29+
# Actual description may consist of several lines. By default, output is
30+
# written to stdout. Test names consist of alphanumeric characters
31+
# including _ and -.
32+
#
33+
#
34+
# History:
35+
# 2002-09-02: created by Peter Oberparleiter <[email protected]>
36+
#
37+
38+
use strict;
39+
use File::Basename;
40+
use Getopt::Long;
41+
42+
43+
# Constants
44+
our $lcov_version = 'LCOV version 1.11';
45+
our $lcov_url = "http://ltp.sourceforge.net/coverage/lcov.php";
46+
our $tool_name = basename($0);
47+
48+
49+
# Prototypes
50+
sub print_usage(*);
51+
sub gen_desc();
52+
sub warn_handler($);
53+
sub die_handler($);
54+
55+
56+
# Global variables
57+
our $help;
58+
our $version;
59+
our $output_filename;
60+
our $input_filename;
61+
62+
63+
#
64+
# Code entry point
65+
#
66+
67+
$SIG{__WARN__} = \&warn_handler;
68+
$SIG{__DIE__} = \&die_handler;
69+
70+
# Prettify version string
71+
$lcov_version =~ s/\$\s*Revision\s*:?\s*(\S+)\s*\$/$1/;
72+
73+
# Parse command line options
74+
if (!GetOptions("output-filename=s" => \$output_filename,
75+
"version" =>\$version,
76+
"help|?" => \$help
77+
))
78+
{
79+
print(STDERR "Use $tool_name --help to get usage information\n");
80+
exit(1);
81+
}
82+
83+
$input_filename = $ARGV[0];
84+
85+
# Check for help option
86+
if ($help)
87+
{
88+
print_usage(*STDOUT);
89+
exit(0);
90+
}
91+
92+
# Check for version option
93+
if ($version)
94+
{
95+
print("$tool_name: $lcov_version\n");
96+
exit(0);
97+
}
98+
99+
100+
# Check for input filename
101+
if (!$input_filename)
102+
{
103+
die("No input filename specified\n".
104+
"Use $tool_name --help to get usage information\n");
105+
}
106+
107+
# Do something
108+
gen_desc();
109+
110+
111+
#
112+
# print_usage(handle)
113+
#
114+
# Write out command line usage information to given filehandle.
115+
#
116+
117+
sub print_usage(*)
118+
{
119+
local *HANDLE = $_[0];
120+
121+
print(HANDLE <<END_OF_USAGE)
122+
Usage: $tool_name [OPTIONS] INPUTFILE
123+
124+
Convert a test case description file into a format as understood by genhtml.
125+
126+
-h, --help Print this help, then exit
127+
-v, --version Print version number, then exit
128+
-o, --output-filename FILENAME Write description to FILENAME
129+
130+
For more information see: $lcov_url
131+
END_OF_USAGE
132+
;
133+
}
134+
135+
136+
#
137+
# gen_desc()
138+
#
139+
# Read text file INPUT_FILENAME and convert the contained description to a
140+
# format as understood by genhtml, i.e.
141+
#
142+
# TN:<test name>
143+
# TD:<test description>
144+
#
145+
# If defined, write output to OUTPUT_FILENAME, otherwise to stdout.
146+
#
147+
# Die on error.
148+
#
149+
150+
sub gen_desc()
151+
{
152+
local *INPUT_HANDLE;
153+
local *OUTPUT_HANDLE;
154+
my $empty_line = "ignore";
155+
156+
open(INPUT_HANDLE, "<", $input_filename)
157+
or die("ERROR: cannot open $input_filename!\n");
158+
159+
# Open output file for writing
160+
if ($output_filename)
161+
{
162+
open(OUTPUT_HANDLE, ">", $output_filename)
163+
or die("ERROR: cannot create $output_filename!\n");
164+
}
165+
else
166+
{
167+
*OUTPUT_HANDLE = *STDOUT;
168+
}
169+
170+
# Process all lines in input file
171+
while (<INPUT_HANDLE>)
172+
{
173+
chomp($_);
174+
175+
if (/^(\w[\w-]*)(\s*)$/)
176+
{
177+
# Matched test name
178+
# Name starts with alphanum or _, continues with
179+
# alphanum, _ or -
180+
print(OUTPUT_HANDLE "TN: $1\n");
181+
$empty_line = "ignore";
182+
}
183+
elsif (/^(\s+)(\S.*?)\s*$/)
184+
{
185+
# Matched test description
186+
if ($empty_line eq "insert")
187+
{
188+
# Write preserved empty line
189+
print(OUTPUT_HANDLE "TD: \n");
190+
}
191+
print(OUTPUT_HANDLE "TD: $2\n");
192+
$empty_line = "observe";
193+
}
194+
elsif (/^\s*$/)
195+
{
196+
# Matched empty line to preserve paragraph separation
197+
# inside description text
198+
if ($empty_line eq "observe")
199+
{
200+
$empty_line = "insert";
201+
}
202+
}
203+
}
204+
205+
# Close output file if defined
206+
if ($output_filename)
207+
{
208+
close(OUTPUT_HANDLE);
209+
}
210+
211+
close(INPUT_HANDLE);
212+
}
213+
214+
sub warn_handler($)
215+
{
216+
my ($msg) = @_;
217+
218+
warn("$tool_name: $msg");
219+
}
220+
221+
sub die_handler($)
222+
{
223+
my ($msg) = @_;
224+
225+
die("$tool_name: $msg");
226+
}

0 commit comments

Comments
 (0)