I'm writing my own Pod and wanted to start unit Testing. But I can't figure out where in my Project to test.
I thought the Example Project was the right place to write my Tests, but from there I don't have internal Access to my DevelopmentPod.
I have to say it's the first XCode Project in which I want to unit test. So I'm not very familiar with it.
Any help on how unit Testing in Cocoapods should be set up is really appreciated.
Related
I have a library project (A) and a Metal library project (M). M is included into A in the "Copy files" phase. That introduces a build dependency, meaning that I can't build A for the simulator because it tries to build M first, and Metal is not supported on the simulator.
That's fine, but the problem is that A contains some unit tests, and when I try to test the project, I get this error message,
Logic Testing Unavailable. Logic testing on iOS devices is not supported. You can only run logic tests on the Simulator.
But I can't build for the Simulator because of the aforementioned dependency...
I read https://medium.com/the-sup-app/bare-metal-working-with-metal-and-the-simulator-70e085e3a45 -- perhaps this could help me removing the dependency of M in A for the simulator, but I'm trying to do this without Cocoapods, purely in Xcode.
Is there any workaround for this?
I ran into this exact same thing over the weekend. Tried to be a good citizen and include unit tests in my Metal project. ;-)
The only way out of this catch-22 is to not use XCTest for writing unit tests but create a separate target that runs as an app on its own. This new target then runs the unit tests.
In the old days I used GHUnit for this but I do not know if there is a suitable replacement for it these days.
Worst case scenario you can write your own little unit testing library that runs the XCTest macros.
I once asked a question related to XCTests. And in one of the answers I was told that it is a common practice to use a separate test target (other than the main app) when running unit tests (at least, in iOS development). I tried to find some sources about it, but I couldn't
I understand, that it is probably a best practice, so I would really like to understand it. Could someone explain to me why is it important, what benefits do I get from it and how should I go about doing it? Links to some articles explaining the issue will be much appreciated.
P.S. I understand that I need special environment for tests (fake in-memory database, mocked networking layer, etc.), but up until now I managed to achieve it without a separate test host. But I believe that there might be a better way.
To answer your points:
Why is using a separate test target important?
Separation of concerns. A unit test target does not have the same kind of structure as a regular app target - it contains a test bundle, which references the app target under test, as well as the test classes and any helper classes required. It is not a duplicate of the app target with test code added to it - in fact it should not even contain the code under test. This means that you don't have to make any special effort to keep the test target in sync with the main app target - the fact that the test bundle loads the main app handles all that for you. (You made a comment on Richard Ross's answer to your previous q suggesting you've run into the difficulties duplication causes already).
How should I go about doing this? (checked on Xcode 7).
Assuming you are wanting to add a target to an existing project that doesn't have any tests, select the main project, and then click on the '+' beneath the list of targets in the project. You can also use the File->New->Target menu option.
You'll see a menu asking you to choose a template for your new target. Select 'Test' and within test select 'iOS Unit Testing Bundle'.
Check the fields in the next screen - they should be correct by default - but you might want to double check the 'Target to be Tested' field value is correct if you have a lot of targets in the project/workspace. Click 'OK' and you should have a functioning unit test bundle, with an example test that you should be able to run using Apple-U or Product->Test You'll still need to #import the app classes if you're using ObjC.
If you are creating a new project, all you need to do is tick the 'Include Unit Test' box when creating the project - no other steps are required.
Apple Docs (with links to relevant WWDC presentations)
Tutorials. Most of the tutorials around are a bit out of date. But not that much has changed, so just look at the docs and figure it out. The two below might be useful, otherwise just google. From a quick glance, most of them seem to assume that the project had unit tests set up at the beginning
http://www.raywenderlich.com/22590/beginning-automated-testing-with-xcode-part-12 (2012/iOS 6, but the process is still broadly the same. Also deals with Jenkins, Git and running tests from the CLI).
Unit testing in OSX - most recent post - not iOS, I know, but more up to date than most of the iOS tutorials (Oct 2015), and gives step by step instructions (including setting the unit test target in the build schemes, which probably won't be necessary in your case). Probably worth a look anyway.
I have recently implemented Localytics to get a better understanding of how our users are using our app.
The integration guide is pretty straight forward. However the unit tests can't be built any longer, when I run them.
The error is familiar to me. This error usually happens if the tested class is not part of the test target membership.
But the SDK _OBJC_CLASS_$_LocalyticsSession provides only a .h file. In order to make it part of the target membership, I needed the .m file, which I don't have.
Has anyone else utilised Localystics and can advice me how to proceed this regarding? Thanks
UPDATE
coneybeare's answer has actually made me try this:
The test target is set to None. But if I change it to target the app itself:
Then it works. However everytime I intend to run the unit tests the whole app has to start in the simulator, which is very irritating (and slow). Am I missing something? How else can I associate the .a code libraries with the test targets?
I don't use Localytics, but inspecing the SDK downloads shows a few .a code libraries. Ensure those are associated with the test targets.
I've got a large iOS project set up with OCUnit tests, some of which are imported from a dependent project, and some of which are local. When I have a failing test in the dependent project, I can click the error, and be transported to the line that's breaking. This isn't working for the local tests. It just takes me to the file, but not the breaking line.
Does anyone know if there is something special I need to do in my unit tests, or configuration of XCode, to get jumping to the broken test working?
(I'm on XCode 4.6.2)
It's not you. Xcode 4 doesn't correctly interpret relative paths like proj1/foo/../../proj2/bar/file.m for unit test failures.
I would like to create a library for iOS applications which uses UIKit. Furthermore I would like to create unit tests for this library. Unfortunately my tests do not work because of UIKit ([UIFont systemFontOfSize:12.0] to be precise).
According to Apple's Unit Testing Guide there are two types of test cases: logic tests and application tests. Application tests seem to be the correct type for tests involving UIKit related stuff but I did not find out about how to set up application tests for libraries. Has anybody ever had the same problem and was able to solve it?
Thanks a lot!
I found a solution to this. You must add a new target to your project that is simply an empty application. Then use that application as your test host following the instructions for doing this with a regular application like here:
Why does instantiating a UIFont in an iphone unit test cause a crash?