SlideShare ist ein Scribd-Unternehmen logo
1 von 23
Writing First Class Unit Tests Best Practices Dennis Doomen | Principal Consultant | Aviva Solutions @ddoomen | www.dennisdoomen.net
Unit tests… Are fast Are automated Are small Run in-memory Unit = Single class…or… Dennis Doomen
Integration tests… Can cross boundaries Are slower Candepend on external resources Dennis Doomen
Otherforms of testing System Testing UsabilityTesting User AcceptanceTesting ATDD Dennis Doomen
My First Attempt… Dennis Doomen
        [TestMethod]        public void FindCustomersTest1()        {            var viewModel = new CustomerManagementViewModel();            string propertyChanged = "";            viewModel.PropertyChanged += (sender, args) => propertyChanged = args.PropertyName;                        viewModel.City = "Washington";            viewModel.MinimumAccountBalance = 10000;            viewModel.Find();            var customers = viewModel.Customers;            Assert.AreEqual(2, customers.Count());            Assert.IsTrue(customers.Any(c => c.Id == 15));            Assert.IsTrue(customers.Any(c => c.Id == 81));                        Assert.AreEqual("Customers", propertyChanged);            viewModel.City = "";            viewModel.MinimumAccountBalance = 0;            propertyChanged = "";            viewModel.Find();            Assert.AreEqual(102, viewModel.Customers.Count());        } IntentionRevealing Small andfocused Clearcauseand effect Test onecondition Independent Repeatable No side-effects
If it is not important for the test, it is very important not to show it… My first attempt…
A small improvement…    [TestMethod]        public void When_searching_it_should_account_for_the_city_and_minimal_account_balance()        {         } My first attempt…
My first attempt… More improvements… Isolate The Ugly Stuff UseDependencyInjection
       [TestMethod]        public void When_searching_it_should_account_for_the_city_and_minimal_account_balance()        {            var  dummyCustomers  = new[] { new Customer(), new Customer()};            var service = new ServiceAgentStub();            service.AddDummyCustomers(dummyCustomers);            var viewModel = new CustomerManagementViewModel(service)            {                City = "Washington",                MinimumAccountBalance = 10000            };            string propertyChanged = null;            viewModel.PropertyChanged += (sender, args) => propertyChanged = args.PropertyName;            viewModel.Find();            Assert.AreEqual(2, viewModel.Customers.Count());                        CollectionAssert.AreEquivalent(viewModel.Customers.ToArray(), dummyCustomers);            Assert.AreEqual("Washington", service.City);            Assert.AreEqual(10000, service.MinimumAccountBalance);            Assert.AreEqual("Customers", propertyChanged);        }
    public class ServiceAgentStub : IServiceAgent    {        private List<Customer> dummyCustomers = new List<Customer>();        public decimal? MinimumAccountBalance { get; set; }        public string City { get; set; }        public void AddDummyCustomers(params Customer[] customers)        {            dummyCustomers.AddRange(customers);        }        public IEnumerable<Customer> FindCustomers(string city, decimal? minimumAccountBalance)        {            City = city;            MinimumAccountBalance = minimumAccountBalance;            return dummyCustomers;        }    }
My first attempt… Some more intentions…
       [TestMethod]        public void When_searching_it_should_account_for_the_city_and_minimal_account_balance()        {            var  dummyCustomers  = new[] { new Customer(), new Customer()};            var service = new ServiceAgentStub();            service.AddDummyCustomers(customer1, customer2);        [TestMethod]        public void When_searching_it_should_account_for_the_city_and_minimal_account_balance()        {             var someCustomer = new CustomerBuilder().Build();            var someOtherCustomer = new CustomerBuilder().Build();            var theServiceAgent = new ServiceAgentStub();            theServiceAgent.AddDummyCustomers(someCustomer, someOtherCustomer);
    public class CustomerBuilder : TestDataBuilder<Customer>    {        private static long nextId = 1;        private string city = "Redmond";        private decimal accountBalance = 100;        protected override Customer OnBuild()        {            return new Customer            {                Id = nextId++,                City = city,                AccountBalance = accountBalance            };        }        public CustomerBuilder InCity(string city)        {            this.city = city;            return this;        }        public CustomerBuilder WithAccountBalance(decimal accountBalance)        {            this.accountBalance = accountBalance;            return this;        }    }
My first attempt… Arrange…act…assert…
My first attempt… State versus interaction
My first attempt… Rules toease unit testing… Test small beforeyou test big Prefer state-basedtesting Keep out of the debugger hell
            //-------------------------------------------------------------------------------------------------------------------            // Assert            //-------------------------------------------------------------------------------------------------------------------            Assert.AreEqual(2, viewModel.Customers.Count());                        var expectedCustomers = new[] { someCustomer, someOtherCustomer};            CollectionAssert.AreEquivalent(viewModel.Customers.ToArray(), expectedCustomers);            Assert.AreEqual("Washington", theServiceAgent.City);            Assert.AreEqual(10000, theServiceAgent.MinimumAccountBalance);            Assert.AreEqual("Customers", changedPropertyName);             //-------------------------------------------------------------------------------------------------------------------            // Assert            //-------------------------------------------------------------------------------------------------------------------            viewModel.Customers.Should().Equal(someCustomers);            theServiceAgent.City.Should().Be("Washington");            theServiceAgent.MinimumAccountBalance.Should().Be(10000m);            changedPropertyName.Should().Be("Customers");
My first attempt… AAA versus BDD-style
Andnowforsomefaking…
Karl Seguin wrote: Refusing Getting too excited Testing everything! Integration testing Discover mocking Mocking everything Becoming effective 28 May 2009 Dennis Doomen
Background InformationJeremy’sLaws of TDD, Test Data Builder, Applying Domain Driven Design (Jimmy Nillson), xUnitPatterns Example Code, FrameworksSilverlightCookbook, Fake It Easy, FluentAssertions
Emaildennis.doomen@avivasolutions.nl Twitter @ddoomen Blogwww.dennisdoomen.net

Weitere ähnliche Inhalte

Andere mochten auch

Garbage collected teardown
Garbage collected teardownGarbage collected teardown
Garbage collected teardown
Hiroyuki Ohnaka
 
Roy Osherove TDD From Scratch
Roy Osherove TDD From ScratchRoy Osherove TDD From Scratch
Roy Osherove TDD From Scratch
Roy Osherove
 
Scrum and Test-driven development
Scrum and Test-driven developmentScrum and Test-driven development
Scrum and Test-driven development
toteb5
 
Unit testing best practices
Unit testing best practicesUnit testing best practices
Unit testing best practices
nickokiss
 
Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...
Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...
Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...
Zohirul Alam Tiemoon
 
UNIT TESTING PPT
UNIT TESTING PPTUNIT TESTING PPT
UNIT TESTING PPT
suhasreddy1
 
Types of Software Testing
Types of Software TestingTypes of Software Testing
Types of Software Testing
Nishant Worah
 

Andere mochten auch (17)

Garbage collected teardown
Garbage collected teardownGarbage collected teardown
Garbage collected teardown
 
Negative Testing
Negative TestingNegative Testing
Negative Testing
 
Roy Osherove TDD From Scratch
Roy Osherove TDD From ScratchRoy Osherove TDD From Scratch
Roy Osherove TDD From Scratch
 
Unit Testing, TDD and ATDD
Unit Testing, TDD and ATDDUnit Testing, TDD and ATDD
Unit Testing, TDD and ATDD
 
A Second Look at Unit Testing by Roy Osherove
A Second Look at Unit Testing by Roy OsheroveA Second Look at Unit Testing by Roy Osherove
A Second Look at Unit Testing by Roy Osherove
 
Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rules
 
NUnit Features Presentation
NUnit Features PresentationNUnit Features Presentation
NUnit Features Presentation
 
TDD And Refactoring
TDD And RefactoringTDD And Refactoring
TDD And Refactoring
 
Scrum and Test-driven development
Scrum and Test-driven developmentScrum and Test-driven development
Scrum and Test-driven development
 
Agile Test Driven Development
Agile Test Driven DevelopmentAgile Test Driven Development
Agile Test Driven Development
 
Better Bullshit Driven Development [SeleniumCamp 2017]
Better Bullshit Driven Development [SeleniumCamp 2017]Better Bullshit Driven Development [SeleniumCamp 2017]
Better Bullshit Driven Development [SeleniumCamp 2017]
 
TDD - Agile
TDD - Agile TDD - Agile
TDD - Agile
 
Unit testing best practices
Unit testing best practicesUnit testing best practices
Unit testing best practices
 
Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...
Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...
Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...
 
Test Driven Development (TDD)
Test Driven Development (TDD)Test Driven Development (TDD)
Test Driven Development (TDD)
 
UNIT TESTING PPT
UNIT TESTING PPTUNIT TESTING PPT
UNIT TESTING PPT
 
Types of Software Testing
Types of Software TestingTypes of Software Testing
Types of Software Testing
 

Mehr von Dennis Doomen

Getting a grip on your code dependencies (2023-10)
Getting a grip on your code dependencies (2023-10)Getting a grip on your code dependencies (2023-10)
Getting a grip on your code dependencies (2023-10)
Dennis Doomen
 
Tools and practices to help you deal with legacy code
Tools and practices to help you deal with legacy codeTools and practices to help you deal with legacy code
Tools and practices to help you deal with legacy code
Dennis Doomen
 

Mehr von Dennis Doomen (20)

Getting a grip on your code dependencies (2023-10)
Getting a grip on your code dependencies (2023-10)Getting a grip on your code dependencies (2023-10)
Getting a grip on your code dependencies (2023-10)
 
Tools and practices to help you deal with legacy code
Tools and practices to help you deal with legacy codeTools and practices to help you deal with legacy code
Tools and practices to help you deal with legacy code
 
What you can learn from an open-source project with 250 million downloads
What you can learn from an open-source project with 250 million downloadsWhat you can learn from an open-source project with 250 million downloads
What you can learn from an open-source project with 250 million downloads
 
Getting a grip on your code dependencies
Getting a grip on your code dependenciesGetting a grip on your code dependencies
Getting a grip on your code dependencies
 
My Laws of Test Driven Development (2023)
My Laws of Test Driven Development (2023)My Laws of Test Driven Development (2023)
My Laws of Test Driven Development (2023)
 
Design patterns for Event Sourcing in .NET
Design patterns for Event Sourcing in .NETDesign patterns for Event Sourcing in .NET
Design patterns for Event Sourcing in .NET
 
Automate Infrastructure with Pulumi and C#
Automate Infrastructure with Pulumi and C#Automate Infrastructure with Pulumi and C#
Automate Infrastructure with Pulumi and C#
 
What is the right unit in unit testing (UpdateConf 2022)
What is the right unit in unit testing (UpdateConf 2022)What is the right unit in unit testing (UpdateConf 2022)
What is the right unit in unit testing (UpdateConf 2022)
 
Slow Event Sourcing (re)projections - Just make them faster!
Slow Event Sourcing (re)projections - Just make them faster!Slow Event Sourcing (re)projections - Just make them faster!
Slow Event Sourcing (re)projections - Just make them faster!
 
50 things software teams should not do.pptx
50 things software teams should not do.pptx50 things software teams should not do.pptx
50 things software teams should not do.pptx
 
What is the right "unit" in unit testing and why it is not a class?
What is the right "unit" in unit testing and why it is not a class?What is the right "unit" in unit testing and why it is not a class?
What is the right "unit" in unit testing and why it is not a class?
 
A lab around the principles and practices for writing maintainable code
A lab around the principles and practices for writing maintainable codeA lab around the principles and practices for writing maintainable code
A lab around the principles and practices for writing maintainable code
 
How to Practice TDD Without Shooting Yourself in the Foot
How to Practice TDD Without Shooting Yourself in the FootHow to Practice TDD Without Shooting Yourself in the Foot
How to Practice TDD Without Shooting Yourself in the Foot
 
Decomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservicesDecomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservices
 
Event Sourcing from the Trenches (DDD Europe 2020)
Event Sourcing from the Trenches (DDD Europe 2020)Event Sourcing from the Trenches (DDD Europe 2020)
Event Sourcing from the Trenches (DDD Europe 2020)
 
Practical introduction to DDD, CQRS and Event Sourcing
Practical introduction to DDD, CQRS and Event SourcingPractical introduction to DDD, CQRS and Event Sourcing
Practical introduction to DDD, CQRS and Event Sourcing
 
How to practice TDD without shooting yourself in the foot
How to practice TDD without shooting yourself in the footHow to practice TDD without shooting yourself in the foot
How to practice TDD without shooting yourself in the foot
 
Decomposing the Monolith (Riga Dev Days 2019)
Decomposing the Monolith (Riga Dev Days 2019)Decomposing the Monolith (Riga Dev Days 2019)
Decomposing the Monolith (Riga Dev Days 2019)
 
A lab around the principles and practices for writing maintainable code (2019)
A lab around the principles and practices for writing maintainable code (2019)A lab around the principles and practices for writing maintainable code (2019)
A lab around the principles and practices for writing maintainable code (2019)
 
Lessons learned from two decades of professional software development
Lessons learned from two decades of professional software developmentLessons learned from two decades of professional software development
Lessons learned from two decades of professional software development
 

Kürzlich hochgeladen

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Kürzlich hochgeladen (20)

Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 

Best practices for writing first class unit tests