SlideShare a Scribd company logo
UNIT TESTING IN UNITY
2019-16-1 Mikko McMenamin
• Forces to write better software architecture
• Makes sure the logic of the methods are working
as they should
• Refactoring and maintaining the codebase is
easier and you’ll have more confidence. No need
to be scared of making changes and improving
the software.
• Find bugs early before even running the software
• Works as up-to-date documentation how the
software and it’s public API should be used
• TDD (Test Driven Development) helps you design
the business logic of your code by breaking it
down into smaller objectives
WHY BOTHER WITH UNIT TESTS?
GETTING STARTED
• Unity uses NUnit testing framework.
https://github.com/nunit/docs/wiki/NUnit-Docum
entation
• Open up the Unity Test Runner window in
Window - General - Test Runner and then press
Create PlayMode Test Assembly Folder. This
will create the Tests folder with the NUnit
assembly file.
• Create a test script by pressing the Create Test
Script in current folder button. This can also be
done in the project view Create - Testing - C#
test script. If you have e.g. a class named
Spawner you want to test, name the test class
SpawnerTests.
REFERENCING ASSEMBLY DEFINITION FILES
• You need to create an assembly definition file in
your scripts folder (Create - Assembly
Definition) so your test assembly is able to
reference all your classes.
• Add this newly created assembly definition to the
reference list of the Tests.asmdef file in your
project/asset window.
• Note that if you're using Unity packages in your
project, such as Text Mesh Pro, you need to
reference its assembly definition file in your
projects assembly definition file.
• If you don’t link the assemblies, the tests classes
are not able to find the your actual game/app
scripts
CREATING THE FIRST UNIT TEST
• Decorate your test method with [Test] attribute for basic NUnit tests
• [UnityTest] behaves like a coroutine in PlayMode. You can skip a frame with yield return
null. This way for example the Update method in Monobehaviour classes gets run.
• The Assert class is used to test the conditions of the test.
• Run all your unit tests with the Run All button in the Test Runner. It will show tests that
passed and tests that failed
• All monobehaviour methods are invoked
• Tests run slower
• Build target is considered
PLAY MODE TESTS
• Awake and Start are not invoked
• Tests run faster (in editor)
• Build target does not matter
EDIT MODE TESTS
PLAY MODE VS EDIT MODE TESTS
STRUCTURING UNIT TESTS
1 ARRANGE - create all the needed objects and set their initial values and states
2 ACT - perform operations on the units to be tested, e.g. call a method
3 ASSERT - check that the outcome is correct and expected
Try to follow the ARRANGE - ACT - ASSERT Principle:
NAMING UNIT TESTS AND USING THE AAA-RULE
● A good naming convention is to start with the name of the method to be tested, followed by a
description of the input or the act phase, and finally what is the expected outcome. Separate the
three with an underscore. In this simple example we test the ReduceValue() method to see if the
new Value of the class is correct after calling the ReduceValue() with an input of 5
GOOD UNIT TESTS:
Don’t have any internal logic
Are simple, clean, maintainable and trustworthy
Isolated from everything else - “Solitary tests”
Not too generic but also not too specific
Only test the public methods of a class - “Don’t expose your privates!”
Test the right things. For example do not test Unity’s internal methods
TESTING MONOBEHAVIOUR CLASSES
● Unity's MonoBehaviour classes cannot be created with the new keyword as they are only
supposed to be added to GameObjects.
● So to test MonoBehaviours, you first need to create a gameobject, then add the class you want to
test with the AddComponent() method.
● MonoBehaviour methods, such as Awake(), Start() and Update() are private and should be kept
private for encapsulation. That is why it's cumbersome to call them in a normal test method. For
this Unity provides us the [UnityTest] attribute, which makes the test method behave like a
coroutine in PlayMode, and also allows to skip a frame in EditMode.
● By waiting for the next frame (or for several frames), the Awake(), Start() and Update() and other
Monobehaviour methods are called automatically.
TESTING MONOBEHAVIOUR CLASSES
INSTANTIATING PREFABS
● It is also possible to load / instantiate prefabs from the Resources folder and test that their
functionality work in isolation like this:
CREATING A SCRIPTABLE OBJECT INSTANCE
● Scriptable Objects are a great way of creating modular and testable code in Unity, as they can act
as mediators between classes or as simple data containers. As Scriptable Objects can exist as
assets in the project, they can essentially be injected to different classes in the Unity inspector.
● However, Scriptable Objects can't be constructed with the new keyword and instead need to be
instantiated with the CreateInstance() method:
SETUP AND TEARDOWN
● The [SetUp] attribute can be used to perform a set of actions before each test method
● Conversely, a method with the [TearDown] attribute is called automatically after each test.
ASSERTIONS
● There are a lot of different ways to use assertions in the test methods. Some examples:
● For more detailed information, refer to the NUnit documentation https://github.com/nunit/docs/wiki
TRUSTWORTHY TESTS
● It is important that you can trust your tests
● Start by writing a failing test and/or write a deliberate bug to see if the test passes
● If a test passes when it should not, there is something wrong with either the test or your code logic
CONSTRUCTING PRIVATE SERIALIZED FIELDS
● Private serialized fields that are assigned in the Unity inspector can be tricky in unit tests. There are
two different ways of setting their values. The first option is to use a public “constructor” method...
CONSTRUCTING PRIVATE SERIALIZED FIELDS
…and then calling the Construct() with the wanted values when setting up the object to be tested
USING REFLECTION FOR PRIVATE SERIALIZED FIELDS
● If you’d rather keep the original script classes intact without cluttering them with construct methods
just for unit tests, you can also use reflection to set values for the private fields:
TESTING EVENTS
TESTING EXCEPTIONS
TEST DOUBLES
● Quite often the methods that we want to test have dependencies to other classes
● To test the class and it’s methods in isolation, we need to create test doubles
● A test double can be used instead of the real object and made to behave like we want to. These are
often called spies, mocks, fakes or dummies.
● Creating test doubles is easy with NSubstitute
● Install NSubstitute via NuGet http://nsubstitute.github.io/
● Go to your .nuget packages folder in your OS user folder and locate the nsubstitute folder
● Copy the NSubstitute.dll file in the lib folder to your Unity project Editor folder
● In your test class, add using NSubstitute;
Installing NSubstitute
USING NSUBSTITUTE
● With NSubstitute, we can force the wanted behaviour on the test double
● In the following example, we set the weapon to return the value 20 as the blast power for weapon
number 2. This could then be used when testing another method that has a dependency to the
weapon and it’s GetBlastPower method.
TEST CASES
● To test the methods with different arguments, you can use test cases
● Both the method arguments and the expected result are given in the [TestCase] attribute
RUNNING TESTS IN CI/CD PIPELINES
● It is possible to run Unity and the test runner from the command line
● This makes it possible to integrate running unit tests as part of the cloud build pipelines
● Example: every time changes are committed to the master branch, the cloud machine runs the unit
tests and informs the user if any test failed
MORE INFORMATION:
● The Art of Unit Testing: with examples in C# by Roy Osherove
● Test Driven Development in Unity Youtube tutorial series by Infallible Code
● Unit Testing for C# Developers Udemy course by Mosh Hamedani
● Unity Test Runner documentation
QUESTIONS?
Mikko McMenamin
@mikkomcmenamin (twitter, instagram)
http://www.linkedin.com/in/mikkomcmenamin
THANK YOU!

More Related Content

What's hot

TestNG Session presented in PB
TestNG Session presented in PBTestNG Session presented in PB
TestNG Session presented in PB
Abhishek Yadav
 
TestNG vs Junit
TestNG vs JunitTestNG vs Junit
TestNG vs Junit
Büşra İçöz
 
Bowling Game Kata C#
Bowling Game Kata C#Bowling Game Kata C#
Bowling Game Kata C#
Dan Stewart
 
Cypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdfCypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdf
bacancytechnology
 
Writing and using Hamcrest Matchers
Writing and using Hamcrest MatchersWriting and using Hamcrest Matchers
Writing and using Hamcrest Matchers
Shai Yallin
 
Java Unit Testing
Java Unit TestingJava Unit Testing
Java Unit Testing
Nayanda Haberty
 
Selenium Testing Project report
Selenium Testing Project reportSelenium Testing Project report
Selenium Testing Project report
Kapil Rajpurohit
 
TestNG Framework
TestNG Framework TestNG Framework
TestNG Framework
Levon Apreyan
 
5 Minute Intro to Stetl
5 Minute Intro to Stetl5 Minute Intro to Stetl
5 Minute Intro to Stetl
Just van den Broecke
 
Booting Android: bootloaders, fastboot and boot images
Booting Android: bootloaders, fastboot and boot imagesBooting Android: bootloaders, fastboot and boot images
Booting Android: bootloaders, fastboot and boot images
Chris Simmonds
 
Grails Simple Login
Grails Simple LoginGrails Simple Login
Grails Simple Loginmoniguna
 
Rozdelenie softveru
Rozdelenie softveruRozdelenie softveru
Rozdelenie softveru
gymmoldava
 
Android Boot Time Optimization
Android Boot Time OptimizationAndroid Boot Time Optimization
Android Boot Time OptimizationKan-Ru Chen
 
Implementing generic JNI hardware control for Kotlin based app on AOSP
Implementing generic JNI hardware control for Kotlin based app on AOSPImplementing generic JNI hardware control for Kotlin based app on AOSP
Implementing generic JNI hardware control for Kotlin based app on AOSP
Cheng Wig
 
testng
testngtestng
Embedded Android Workshop
Embedded Android WorkshopEmbedded Android Workshop
Embedded Android Workshop
Opersys inc.
 
Selenium IDE Tutorial For Beginners | Selenium IDE Tutorial | What Is Seleniu...
Selenium IDE Tutorial For Beginners | Selenium IDE Tutorial | What Is Seleniu...Selenium IDE Tutorial For Beginners | Selenium IDE Tutorial | What Is Seleniu...
Selenium IDE Tutorial For Beginners | Selenium IDE Tutorial | What Is Seleniu...
Simplilearn
 
Introduction to Automation Testing
Introduction to Automation TestingIntroduction to Automation Testing
Introduction to Automation Testing
Archana Krushnan
 

What's hot (20)

TestNG Session presented in PB
TestNG Session presented in PBTestNG Session presented in PB
TestNG Session presented in PB
 
Android Multimedia Support
Android Multimedia SupportAndroid Multimedia Support
Android Multimedia Support
 
TestNG vs Junit
TestNG vs JunitTestNG vs Junit
TestNG vs Junit
 
Bowling Game Kata C#
Bowling Game Kata C#Bowling Game Kata C#
Bowling Game Kata C#
 
Junit
JunitJunit
Junit
 
Cypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdfCypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdf
 
Writing and using Hamcrest Matchers
Writing and using Hamcrest MatchersWriting and using Hamcrest Matchers
Writing and using Hamcrest Matchers
 
Java Unit Testing
Java Unit TestingJava Unit Testing
Java Unit Testing
 
Selenium Testing Project report
Selenium Testing Project reportSelenium Testing Project report
Selenium Testing Project report
 
TestNG Framework
TestNG Framework TestNG Framework
TestNG Framework
 
5 Minute Intro to Stetl
5 Minute Intro to Stetl5 Minute Intro to Stetl
5 Minute Intro to Stetl
 
Booting Android: bootloaders, fastboot and boot images
Booting Android: bootloaders, fastboot and boot imagesBooting Android: bootloaders, fastboot and boot images
Booting Android: bootloaders, fastboot and boot images
 
Grails Simple Login
Grails Simple LoginGrails Simple Login
Grails Simple Login
 
Rozdelenie softveru
Rozdelenie softveruRozdelenie softveru
Rozdelenie softveru
 
Android Boot Time Optimization
Android Boot Time OptimizationAndroid Boot Time Optimization
Android Boot Time Optimization
 
Implementing generic JNI hardware control for Kotlin based app on AOSP
Implementing generic JNI hardware control for Kotlin based app on AOSPImplementing generic JNI hardware control for Kotlin based app on AOSP
Implementing generic JNI hardware control for Kotlin based app on AOSP
 
testng
testngtestng
testng
 
Embedded Android Workshop
Embedded Android WorkshopEmbedded Android Workshop
Embedded Android Workshop
 
Selenium IDE Tutorial For Beginners | Selenium IDE Tutorial | What Is Seleniu...
Selenium IDE Tutorial For Beginners | Selenium IDE Tutorial | What Is Seleniu...Selenium IDE Tutorial For Beginners | Selenium IDE Tutorial | What Is Seleniu...
Selenium IDE Tutorial For Beginners | Selenium IDE Tutorial | What Is Seleniu...
 
Introduction to Automation Testing
Introduction to Automation TestingIntroduction to Automation Testing
Introduction to Automation Testing
 

Similar to Unit testing in Unity

Beginners - Get Started With Unit Testing in .NET
Beginners - Get Started With Unit Testing in .NETBeginners - Get Started With Unit Testing in .NET
Beginners - Get Started With Unit Testing in .NET
Baskar K
 
Write unit test from scratch
Write unit test from scratchWrite unit test from scratch
Write unit test from scratch
Wen-Shih Chao
 
Project Onion unit test environment
Project Onion unit test environmentProject Onion unit test environment
Project Onion unit test environment
Abhinav Jha
 
Automation testing
Automation testingAutomation testing
Automation testing
Vivin Chityappa
 
An insight to test driven development and unit testing
An insight to test driven development and unit testingAn insight to test driven development and unit testing
An insight to test driven development and unit testing
Dharmendra Prasad
 
Test Driven Development with Sql Server
Test Driven Development with Sql ServerTest Driven Development with Sql Server
Test Driven Development with Sql Server
David P. Moore
 
Unit Testing in .NET Core 7.0 with XUnit.pptx
Unit Testing in .NET Core 7.0 with XUnit.pptxUnit Testing in .NET Core 7.0 with XUnit.pptx
Unit Testing in .NET Core 7.0 with XUnit.pptx
Knoldus Inc.
 
Junit
JunitJunit
Unit Testing in Angular
Unit Testing in AngularUnit Testing in Angular
Unit Testing in Angular
Knoldus Inc.
 
JUnit- A Unit Testing Framework
JUnit- A Unit Testing FrameworkJUnit- A Unit Testing Framework
JUnit- A Unit Testing Framework
Onkar Deshpande
 
Unit testing (eng)
Unit testing (eng)Unit testing (eng)
Unit testing (eng)
Anatoliy Okhotnikov
 
Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++
Hong Le Van
 
Software Testing
Software TestingSoftware Testing
Software Testing
AdroitLogic
 
Munit In Mule 4 | Patna MuleSoft Meetup #26
Munit In Mule 4 | Patna MuleSoft Meetup #26Munit In Mule 4 | Patna MuleSoft Meetup #26
Munit In Mule 4 | Patna MuleSoft Meetup #26
shyamraj55
 
TDD Workshop UTN 2012
TDD Workshop UTN 2012TDD Workshop UTN 2012
TDD Workshop UTN 2012
Facundo Farias
 
J unit presentation
J unit presentationJ unit presentation
J unit presentationPriya Sharma
 
JUnit Presentation
JUnit PresentationJUnit Presentation
JUnit Presentation
priya_trivedi
 
Unit Testing in Flutter - From Workflow Essentials to Complex Scenarios
Unit Testing in Flutter - From Workflow Essentials to Complex ScenariosUnit Testing in Flutter - From Workflow Essentials to Complex Scenarios
Unit Testing in Flutter - From Workflow Essentials to Complex Scenarios
Flutter Agency
 

Similar to Unit testing in Unity (20)

Beginners - Get Started With Unit Testing in .NET
Beginners - Get Started With Unit Testing in .NETBeginners - Get Started With Unit Testing in .NET
Beginners - Get Started With Unit Testing in .NET
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Write unit test from scratch
Write unit test from scratchWrite unit test from scratch
Write unit test from scratch
 
Project Onion unit test environment
Project Onion unit test environmentProject Onion unit test environment
Project Onion unit test environment
 
Automation testing
Automation testingAutomation testing
Automation testing
 
An insight to test driven development and unit testing
An insight to test driven development and unit testingAn insight to test driven development and unit testing
An insight to test driven development and unit testing
 
Test Driven Development with Sql Server
Test Driven Development with Sql ServerTest Driven Development with Sql Server
Test Driven Development with Sql Server
 
Unit Testing in .NET Core 7.0 with XUnit.pptx
Unit Testing in .NET Core 7.0 with XUnit.pptxUnit Testing in .NET Core 7.0 with XUnit.pptx
Unit Testing in .NET Core 7.0 with XUnit.pptx
 
Junit
JunitJunit
Junit
 
Unit Testing in Angular
Unit Testing in AngularUnit Testing in Angular
Unit Testing in Angular
 
JUnit- A Unit Testing Framework
JUnit- A Unit Testing FrameworkJUnit- A Unit Testing Framework
JUnit- A Unit Testing Framework
 
Unit testing (eng)
Unit testing (eng)Unit testing (eng)
Unit testing (eng)
 
Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++
 
Software Testing
Software TestingSoftware Testing
Software Testing
 
Munit In Mule 4 | Patna MuleSoft Meetup #26
Munit In Mule 4 | Patna MuleSoft Meetup #26Munit In Mule 4 | Patna MuleSoft Meetup #26
Munit In Mule 4 | Patna MuleSoft Meetup #26
 
TDD Workshop UTN 2012
TDD Workshop UTN 2012TDD Workshop UTN 2012
TDD Workshop UTN 2012
 
J unit presentation
J unit presentationJ unit presentation
J unit presentation
 
JUnit Presentation
JUnit PresentationJUnit Presentation
JUnit Presentation
 
Unit testing basic
Unit testing basicUnit testing basic
Unit testing basic
 
Unit Testing in Flutter - From Workflow Essentials to Complex Scenarios
Unit Testing in Flutter - From Workflow Essentials to Complex ScenariosUnit Testing in Flutter - From Workflow Essentials to Complex Scenarios
Unit Testing in Flutter - From Workflow Essentials to Complex Scenarios
 

Recently uploaded

JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 

Recently uploaded (20)

JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 

Unit testing in Unity

  • 1. UNIT TESTING IN UNITY 2019-16-1 Mikko McMenamin
  • 2. • Forces to write better software architecture • Makes sure the logic of the methods are working as they should • Refactoring and maintaining the codebase is easier and you’ll have more confidence. No need to be scared of making changes and improving the software. • Find bugs early before even running the software • Works as up-to-date documentation how the software and it’s public API should be used • TDD (Test Driven Development) helps you design the business logic of your code by breaking it down into smaller objectives WHY BOTHER WITH UNIT TESTS?
  • 3. GETTING STARTED • Unity uses NUnit testing framework. https://github.com/nunit/docs/wiki/NUnit-Docum entation • Open up the Unity Test Runner window in Window - General - Test Runner and then press Create PlayMode Test Assembly Folder. This will create the Tests folder with the NUnit assembly file. • Create a test script by pressing the Create Test Script in current folder button. This can also be done in the project view Create - Testing - C# test script. If you have e.g. a class named Spawner you want to test, name the test class SpawnerTests.
  • 4. REFERENCING ASSEMBLY DEFINITION FILES • You need to create an assembly definition file in your scripts folder (Create - Assembly Definition) so your test assembly is able to reference all your classes. • Add this newly created assembly definition to the reference list of the Tests.asmdef file in your project/asset window. • Note that if you're using Unity packages in your project, such as Text Mesh Pro, you need to reference its assembly definition file in your projects assembly definition file. • If you don’t link the assemblies, the tests classes are not able to find the your actual game/app scripts
  • 5. CREATING THE FIRST UNIT TEST • Decorate your test method with [Test] attribute for basic NUnit tests • [UnityTest] behaves like a coroutine in PlayMode. You can skip a frame with yield return null. This way for example the Update method in Monobehaviour classes gets run. • The Assert class is used to test the conditions of the test. • Run all your unit tests with the Run All button in the Test Runner. It will show tests that passed and tests that failed
  • 6. • All monobehaviour methods are invoked • Tests run slower • Build target is considered PLAY MODE TESTS • Awake and Start are not invoked • Tests run faster (in editor) • Build target does not matter EDIT MODE TESTS PLAY MODE VS EDIT MODE TESTS
  • 7. STRUCTURING UNIT TESTS 1 ARRANGE - create all the needed objects and set their initial values and states 2 ACT - perform operations on the units to be tested, e.g. call a method 3 ASSERT - check that the outcome is correct and expected Try to follow the ARRANGE - ACT - ASSERT Principle:
  • 8. NAMING UNIT TESTS AND USING THE AAA-RULE ● A good naming convention is to start with the name of the method to be tested, followed by a description of the input or the act phase, and finally what is the expected outcome. Separate the three with an underscore. In this simple example we test the ReduceValue() method to see if the new Value of the class is correct after calling the ReduceValue() with an input of 5
  • 9. GOOD UNIT TESTS: Don’t have any internal logic Are simple, clean, maintainable and trustworthy Isolated from everything else - “Solitary tests” Not too generic but also not too specific Only test the public methods of a class - “Don’t expose your privates!” Test the right things. For example do not test Unity’s internal methods
  • 10. TESTING MONOBEHAVIOUR CLASSES ● Unity's MonoBehaviour classes cannot be created with the new keyword as they are only supposed to be added to GameObjects. ● So to test MonoBehaviours, you first need to create a gameobject, then add the class you want to test with the AddComponent() method. ● MonoBehaviour methods, such as Awake(), Start() and Update() are private and should be kept private for encapsulation. That is why it's cumbersome to call them in a normal test method. For this Unity provides us the [UnityTest] attribute, which makes the test method behave like a coroutine in PlayMode, and also allows to skip a frame in EditMode. ● By waiting for the next frame (or for several frames), the Awake(), Start() and Update() and other Monobehaviour methods are called automatically.
  • 12. INSTANTIATING PREFABS ● It is also possible to load / instantiate prefabs from the Resources folder and test that their functionality work in isolation like this:
  • 13. CREATING A SCRIPTABLE OBJECT INSTANCE ● Scriptable Objects are a great way of creating modular and testable code in Unity, as they can act as mediators between classes or as simple data containers. As Scriptable Objects can exist as assets in the project, they can essentially be injected to different classes in the Unity inspector. ● However, Scriptable Objects can't be constructed with the new keyword and instead need to be instantiated with the CreateInstance() method:
  • 14. SETUP AND TEARDOWN ● The [SetUp] attribute can be used to perform a set of actions before each test method ● Conversely, a method with the [TearDown] attribute is called automatically after each test.
  • 15. ASSERTIONS ● There are a lot of different ways to use assertions in the test methods. Some examples: ● For more detailed information, refer to the NUnit documentation https://github.com/nunit/docs/wiki
  • 16. TRUSTWORTHY TESTS ● It is important that you can trust your tests ● Start by writing a failing test and/or write a deliberate bug to see if the test passes ● If a test passes when it should not, there is something wrong with either the test or your code logic
  • 17. CONSTRUCTING PRIVATE SERIALIZED FIELDS ● Private serialized fields that are assigned in the Unity inspector can be tricky in unit tests. There are two different ways of setting their values. The first option is to use a public “constructor” method...
  • 18. CONSTRUCTING PRIVATE SERIALIZED FIELDS …and then calling the Construct() with the wanted values when setting up the object to be tested
  • 19. USING REFLECTION FOR PRIVATE SERIALIZED FIELDS ● If you’d rather keep the original script classes intact without cluttering them with construct methods just for unit tests, you can also use reflection to set values for the private fields:
  • 22. TEST DOUBLES ● Quite often the methods that we want to test have dependencies to other classes ● To test the class and it’s methods in isolation, we need to create test doubles ● A test double can be used instead of the real object and made to behave like we want to. These are often called spies, mocks, fakes or dummies. ● Creating test doubles is easy with NSubstitute ● Install NSubstitute via NuGet http://nsubstitute.github.io/ ● Go to your .nuget packages folder in your OS user folder and locate the nsubstitute folder ● Copy the NSubstitute.dll file in the lib folder to your Unity project Editor folder ● In your test class, add using NSubstitute; Installing NSubstitute
  • 23. USING NSUBSTITUTE ● With NSubstitute, we can force the wanted behaviour on the test double ● In the following example, we set the weapon to return the value 20 as the blast power for weapon number 2. This could then be used when testing another method that has a dependency to the weapon and it’s GetBlastPower method.
  • 24. TEST CASES ● To test the methods with different arguments, you can use test cases ● Both the method arguments and the expected result are given in the [TestCase] attribute
  • 25. RUNNING TESTS IN CI/CD PIPELINES ● It is possible to run Unity and the test runner from the command line ● This makes it possible to integrate running unit tests as part of the cloud build pipelines ● Example: every time changes are committed to the master branch, the cloud machine runs the unit tests and informs the user if any test failed
  • 26. MORE INFORMATION: ● The Art of Unit Testing: with examples in C# by Roy Osherove ● Test Driven Development in Unity Youtube tutorial series by Infallible Code ● Unit Testing for C# Developers Udemy course by Mosh Hamedani ● Unity Test Runner documentation
  • 28. Mikko McMenamin @mikkomcmenamin (twitter, instagram) http://www.linkedin.com/in/mikkomcmenamin THANK YOU!