The Problems
Limitations
Dependencies
The other problem is that you can't really run anything which is found in the UnityEngine namespace, including Debug.Log. Those lines will probably be present in your code and you have to have a way to test them, but this is solvable.
The Solutions
Visual Studio
First of all, we've created a new Test Project in Visual Studio Express (which is free to use!). To this solution we added the project "Assembly-CSharp-vs.csproj" and connected it by dependency (reference) to the main test project. Now we can test our code as it's already referenced to UnityEngine and the actual csproj will be automatically updated when we edit it. We also used the built in testing tools of Visual Studio for simplicity.
Perforce
We've set up a Perforce system on Assembla (This is a bit tricky, i'll write more about it in the next post.) and set up a Jenkins server to monitor the perforce depot (it's like a repository for SVN) and run the tests in our project. You can do it with any combination of Source Control, hosting service (or your own repository) and Continuous Integration server.
Workarounds
Setting Source Control on the build machine
Hiding Unity functionality
If you try running the tests you'll probably receive this nonsensical error:
Test method ############## threw exception:
System.Security.SecurityException: ECall methods must be packaged into a system module.
This actually mean that you tried running something from UnityEngine in VisualStudio. Usually by following the trace you'll be able to get to the exact method it occurs in. Also, it seems to mostly come from rogue Debug.Log calls (although some of calls seem to originate from PlayerPrefs or WWW).s
One options is to remove them, but this can be hazardous if you want to keep logs at runtime. Our solution had 2 parts to it:
1) Replace Debug.Log with a modified log4net module. The only modification we added was to print Debug.Log whenever you log anything with the log4net module (also Debug.LogWarning and Debug.LogError when applicable). This means we're using log.Debug(string) instead of Debug.Log(string). This also helps us to send the logs somewhere safe or keep them in a file when necessary and not just print them in the editor.
2) Now that all the Debug.Log lines are moved into one file, we can hide them. The ideal solution would be to find a precompiled define statement which will only be compiled in unity (the editor or any other build platform, but not in Visual Studio). So we did just that. We added a #IN_UNITY precompiler header which only unity can read so it's false by default. In order to make Unity know about it we put two files in the Asset folder (the file names and their location is important) and called them smcs.rsp and gmcs.rsp. For more information about what are those files, look here (Ctrl+F for smcs). Then we put this line into both files:
-define:IN_UNITY
And that's it! Now all those line will work from unity but not from Visual Studio.
Conclusion
The next post will include some information on how to make Jenkins work with Perforce in Assemble and why we couldn't use TeamCity. Hope you can make use of all this information. Please comment on this post if you have any further inquiries!
No comments:
Post a Comment