SlideShare a Scribd company logo
1 of 23
TDD on
Play Framework
Vu Hai Ninh
AGENDA
I. What is TDD
II. Benefits
III.Limitations
IV. TDD on Play Framework
WHAT IS TDD
Test-Driven Development (or test driven
design) is a methodology.
Common TDD misconception:
TDD is not about testing
TDD is about design and development
By testing first you design your code
Short development iterations
Based on requirement and pre-written test cases
Produces code necessary to pass that iteration's test
Refactor both code and tests
HOW DOES TDD HELP
I. TDD helps you produce clean working code
that fulfills requirements
II. Write Test Code
A. Code that fulfills requirements
III.Write Functional Code
A. Working code that fulfills requirements
IV. Refactor
A. Clean working code that fulfills
requirements
TDD CYCLE
TDD BASICS - UNIT TESTING
Red, Green, Refactor
I. Make it Fail
A. No code without a failing test
II. Make it Work
A. As simply as possible
III.Make it Better
A. Refactor
BENEFITS
Confidence in change
Increase confidence in code
Fearlessly change your code
Document requirements
Discover usability issues early
Regression testing = Stable software =
Quality software
Limitation
We need know about
I. Interfaces
II. Dependency Injection
III.Mock
IV. The builder and fluent interface patterns.
V. Refactoring
TOP FIVE EXCUSES FOR NOT UNIT
TESTI. Don’t have time to unit test.
II. The client pays me to develop code, not write
unit test.
III.I am supporting a legacy application without
unit tests.
IV. QA and User Acceptance Testing is far more
effective in finding bugs.
V. I don’t know how to unit test, or I don’t know
how to write good unit tests.
Play Test
Sbt test
Run all test classes
Sbt testOnly namespace.classTest
Run for only classTest
Change database when running test
Modify build.sbt
javaOptions in Test += "-
Dconfig.file=conf/application.test.conf"
We have
I. Unit Test -> Apply
II. Functional Test -> Apply
III.Selenium Test -> Optional
Use MVC application Model
Application.conf
# Database configuration
# ~~~~~
# You can declare as many datasources as you want.
# By convention, the default datasource is named `default`
db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://xx.x.x.xx:xxxx/yyy"
db.default.username=xxx
db.default.password="xxx"
db.default.logSql=true
DAO Class
public class CompanyRepository {
public CompletionStage<Map<String, String>> options() {
return supplyAsync(() ->
ebeanServer.find(Company.class).orderBy("name").findList(),
executionContext).thenApply(list -> {
HashMap<String, String> options = new LinkedHashMap<String, String>();
for (Company c : list) {
options.put(c.id.toString(), c.getName());
}
return options;
});
}
}
Test DAO Class
sbt testOnly respository.CompanyRepositoryTest
public class CompanyRepositoryTest extends WithApplication {
@Test
public void options() throws Exception {
final CompanyRepository companyRepository =
app.injector().instanceOf(CompanyRepository.class);
final CompletionStage<Map<String, String>> stage =
companyRepository.options();
await().atMost(1, SECONDS).until(() ->
assertThat(stage.toCompletableFuture()).isCompletedWithValueMatching(companyMap -> {
return companyMap.size() == 42;
})
);
}
}
Controller Class
public class HomeController extends Controller {
public CompletionStage<Result> edit(Long id) {
CompletionStage<Map<String, String>> companiesFuture =
companyRepository.options();
return
computerRepository.lookup(id).thenCombineAsync(companiesFuture, (computerOptional,
companies) -> {
Computer c = computerOptional.get();
Form<Computer> computerForm =
formFactory.form(Computer.class).fill(c);
return ok(views.html.computer.editForm.render(id, computerForm,
companies));
}, httpExecutionContext.current());
}
Test Controller Class
public class HomeControllerTest extends WithApplication {
ComputerRepository computerRepository =
mock(ComputerRepository.class);
@Override
protected Application provideApplication() {
return new
GuiceApplicationBuilder().overrides(bind(ComputerRepository.class).toInstance(computerRe
pository)).build();
}
@Test
public void edit() {
final ComputerRepository computerRepository =
app.injector().instanceOf(ComputerRepository.class);
CompletionStage<Optional<Computer>> computer =
CompletableFuture.supplyAsync(()->{
return Optional.of(new Computer());
});
when(computerRepository.lookup(21L)).thenReturn(computer);
final CompletionStage<Optional<Computer>> stage =
computerRepository.lookup(21L);
View template
@main("404 - Page Not Found"){
<div class="jumbotron">
<h1>404</h1>
<h3>Page Not Found</h3>
</div>
Test View Template
public class Errors_404Test {
@Test
public void renderTemplate() {
HttpExecutionContext httpExecutionContext =
app.injector().instanceOf(HttpExecutionContext.class);
supplyAsync(()-> {
Content html = views.html.errors._404.render();
assertEquals("text/html", html.contentType());
assertTrue(contentAsString(html).contains("Page Not Found"));
return 0;
}, httpExecutionContext.current());
}
}
FunctionalTest
public class FunctionalTest extends WithApplication {
@Test
public void redirectHomePage() {
Result result = route(app, controllers.routes.HomeController.index());
assertThat(result.status()).isEqualTo(SEE_OTHER);
assertThat(result.redirectLocation().get()).isEqualTo("/computers");
}
....
Q&A
THANK YOU
FOR
YOUR
ATTENTION

More Related Content

What's hot

Tdd in php a brief example
Tdd in php   a brief exampleTdd in php   a brief example
Tdd in php a brief example
Jeremy Kendall
 

What's hot (20)

Laravel Unit Testing
Laravel Unit TestingLaravel Unit Testing
Laravel Unit Testing
 
Tdd in php a brief example
Tdd in php   a brief exampleTdd in php   a brief example
Tdd in php a brief example
 
Automated php unit testing in drupal 8
Automated php unit testing in drupal 8Automated php unit testing in drupal 8
Automated php unit testing in drupal 8
 
UI Testing
UI TestingUI Testing
UI Testing
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails Apps
 
TDD In Practice
TDD In PracticeTDD In Practice
TDD In Practice
 
A Deep Dive into the W3C WebDriver Specification
A Deep Dive into the W3C WebDriver SpecificationA Deep Dive into the W3C WebDriver Specification
A Deep Dive into the W3C WebDriver Specification
 
Developers Testing - Girl Code at bloomon
Developers Testing - Girl Code at bloomonDevelopers Testing - Girl Code at bloomon
Developers Testing - Girl Code at bloomon
 
Scripting robot
Scripting robotScripting robot
Scripting robot
 
Integration Group - Robot Framework
Integration Group - Robot Framework Integration Group - Robot Framework
Integration Group - Robot Framework
 
Automation testing with Drupal 8
Automation testing with Drupal 8Automation testing with Drupal 8
Automation testing with Drupal 8
 
CI / CD w/ Codeception
CI / CD w/ CodeceptionCI / CD w/ Codeception
CI / CD w/ Codeception
 
XPDays Ukraine: Legacy
XPDays Ukraine: LegacyXPDays Ukraine: Legacy
XPDays Ukraine: Legacy
 
Top 20 cucumber interview questions for sdet
Top 20 cucumber interview questions for sdetTop 20 cucumber interview questions for sdet
Top 20 cucumber interview questions for sdet
 
Acceptance Test Driven Development and Robot Framework
Acceptance Test Driven Development and Robot FrameworkAcceptance Test Driven Development and Robot Framework
Acceptance Test Driven Development and Robot Framework
 
Test all the things! Automated testing with Drupal 8
Test all the things! Automated testing with Drupal 8Test all the things! Automated testing with Drupal 8
Test all the things! Automated testing with Drupal 8
 
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLEAN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
 
Top 20 Junit interview questions for sdet
Top 20 Junit interview questions for sdetTop 20 Junit interview questions for sdet
Top 20 Junit interview questions for sdet
 
Introduction to Robot Framework
Introduction to Robot FrameworkIntroduction to Robot Framework
Introduction to Robot Framework
 
How we tested our code "Google way"
How we tested our code "Google way"How we tested our code "Google way"
How we tested our code "Google way"
 

Similar to Tdd on play framework

Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
bhochhi
 
Evaluating Test Driven Development And Parameterized Unit Testing In Dot Net ...
Evaluating Test Driven Development And Parameterized Unit Testing In Dot Net ...Evaluating Test Driven Development And Parameterized Unit Testing In Dot Net ...
Evaluating Test Driven Development And Parameterized Unit Testing In Dot Net ...
mdfachowdhury
 

Similar to Tdd on play framework (20)

Binary Studio Academy: .NET Code Testing
Binary Studio Academy: .NET Code TestingBinary Studio Academy: .NET Code Testing
Binary Studio Academy: .NET Code Testing
 
NET Code Testing
NET Code TestingNET Code Testing
NET Code Testing
 
Database continuous integration, unit test and functional test
Database continuous integration, unit test and functional testDatabase continuous integration, unit test and functional test
Database continuous integration, unit test and functional test
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Apache DeltaSpike the CDI toolbox
Apache DeltaSpike the CDI toolboxApache DeltaSpike the CDI toolbox
Apache DeltaSpike the CDI toolbox
 
Apache DeltaSpike: The CDI Toolbox
Apache DeltaSpike: The CDI ToolboxApache DeltaSpike: The CDI Toolbox
Apache DeltaSpike: The CDI Toolbox
 
TDD- Test Driven Development
TDD- Test Driven DevelopmentTDD- Test Driven Development
TDD- Test Driven Development
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Test-Driven Development In Action
Test-Driven Development In ActionTest-Driven Development In Action
Test-Driven Development In Action
 
Testing in Craft CMS
Testing in Craft CMSTesting in Craft CMS
Testing in Craft CMS
 
Desenvolvendo um Framework com TDD - Um Diário de Bordo - Agile Trends 2014
Desenvolvendo um Framework com TDD - Um Diário de Bordo - Agile Trends 2014Desenvolvendo um Framework com TDD - Um Diário de Bordo - Agile Trends 2014
Desenvolvendo um Framework com TDD - Um Diário de Bordo - Agile Trends 2014
 
TDD - Agile
TDD - Agile TDD - Agile
TDD - Agile
 
Python and test
Python and testPython and test
Python and test
 
Evaluating Test Driven Development And Parameterized Unit Testing In Dot Net ...
Evaluating Test Driven Development And Parameterized Unit Testing In Dot Net ...Evaluating Test Driven Development And Parameterized Unit Testing In Dot Net ...
Evaluating Test Driven Development And Parameterized Unit Testing In Dot Net ...
 
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
 
Stopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestStopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under Test
 
Improve DB2 testing environments
Improve DB2 testing environmentsImprove DB2 testing environments
Improve DB2 testing environments
 
Test driven development v1.0
Test driven development v1.0Test driven development v1.0
Test driven development v1.0
 
Building a Testable Data Access Layer
Building a Testable Data Access LayerBuilding a Testable Data Access Layer
Building a Testable Data Access Layer
 
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
 

Recently uploaded

Abortion Pill Prices Rustenburg [(+27832195400*)] 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Rustenburg [(+27832195400*)] 🏥 Women's Abortion Clinic i...Abortion Pill Prices Rustenburg [(+27832195400*)] 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Rustenburg [(+27832195400*)] 🏥 Women's Abortion Clinic i...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
drm1699
 
Abortion Pill Prices Jane Furse ](+27832195400*)[🏥Women's Abortion Clinic in ...
Abortion Pill Prices Jane Furse ](+27832195400*)[🏥Women's Abortion Clinic in ...Abortion Pill Prices Jane Furse ](+27832195400*)[🏥Women's Abortion Clinic in ...
Abortion Pill Prices Jane Furse ](+27832195400*)[🏥Women's Abortion Clinic in ...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 

Recently uploaded (20)

Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
 
Abortion Pill Prices Rustenburg [(+27832195400*)] 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Rustenburg [(+27832195400*)] 🏥 Women's Abortion Clinic i...Abortion Pill Prices Rustenburg [(+27832195400*)] 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Rustenburg [(+27832195400*)] 🏥 Women's Abortion Clinic i...
 
Encryption Recap: A Refresher on Key Concepts
Encryption Recap: A Refresher on Key ConceptsEncryption Recap: A Refresher on Key Concepts
Encryption Recap: A Refresher on Key Concepts
 
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
 
Abortion Clinic in Bloemfontein [(+27832195400*)]🏥Safe Abortion Pills In Bloe...
Abortion Clinic in Bloemfontein [(+27832195400*)]🏥Safe Abortion Pills In Bloe...Abortion Clinic in Bloemfontein [(+27832195400*)]🏥Safe Abortion Pills In Bloe...
Abortion Clinic in Bloemfontein [(+27832195400*)]🏥Safe Abortion Pills In Bloe...
 
From Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST APIFrom Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST API
 
Your Ultimate Web Studio for Streaming Anywhere | Evmux
Your Ultimate Web Studio for Streaming Anywhere | EvmuxYour Ultimate Web Studio for Streaming Anywhere | Evmux
Your Ultimate Web Studio for Streaming Anywhere | Evmux
 
The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)
 
Effective Strategies for Wix's Scaling challenges - GeeCon
Effective Strategies for Wix's Scaling challenges - GeeConEffective Strategies for Wix's Scaling challenges - GeeCon
Effective Strategies for Wix's Scaling challenges - GeeCon
 
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
 
Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...
Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...
Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...
 
Lessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdfLessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdf
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
Transformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksTransformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with Links
 
Evolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI EraEvolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI Era
 
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdfAzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
 
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
 
OpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCAOpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCA
 
Abortion Pill Prices Jane Furse ](+27832195400*)[🏥Women's Abortion Clinic in ...
Abortion Pill Prices Jane Furse ](+27832195400*)[🏥Women's Abortion Clinic in ...Abortion Pill Prices Jane Furse ](+27832195400*)[🏥Women's Abortion Clinic in ...
Abortion Pill Prices Jane Furse ](+27832195400*)[🏥Women's Abortion Clinic in ...
 
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
 

Tdd on play framework

  • 2. AGENDA I. What is TDD II. Benefits III.Limitations IV. TDD on Play Framework
  • 3. WHAT IS TDD Test-Driven Development (or test driven design) is a methodology. Common TDD misconception: TDD is not about testing TDD is about design and development By testing first you design your code Short development iterations Based on requirement and pre-written test cases Produces code necessary to pass that iteration's test Refactor both code and tests
  • 4. HOW DOES TDD HELP I. TDD helps you produce clean working code that fulfills requirements II. Write Test Code A. Code that fulfills requirements III.Write Functional Code A. Working code that fulfills requirements IV. Refactor A. Clean working code that fulfills requirements
  • 6. TDD BASICS - UNIT TESTING Red, Green, Refactor I. Make it Fail A. No code without a failing test II. Make it Work A. As simply as possible III.Make it Better A. Refactor
  • 7. BENEFITS Confidence in change Increase confidence in code Fearlessly change your code Document requirements Discover usability issues early Regression testing = Stable software = Quality software
  • 9. We need know about I. Interfaces II. Dependency Injection III.Mock IV. The builder and fluent interface patterns. V. Refactoring
  • 10. TOP FIVE EXCUSES FOR NOT UNIT TESTI. Don’t have time to unit test. II. The client pays me to develop code, not write unit test. III.I am supporting a legacy application without unit tests. IV. QA and User Acceptance Testing is far more effective in finding bugs. V. I don’t know how to unit test, or I don’t know how to write good unit tests.
  • 11. Play Test Sbt test Run all test classes Sbt testOnly namespace.classTest Run for only classTest Change database when running test Modify build.sbt javaOptions in Test += "- Dconfig.file=conf/application.test.conf"
  • 12. We have I. Unit Test -> Apply II. Functional Test -> Apply III.Selenium Test -> Optional
  • 14. Application.conf # Database configuration # ~~~~~ # You can declare as many datasources as you want. # By convention, the default datasource is named `default` db.default.driver=com.mysql.jdbc.Driver db.default.url="jdbc:mysql://xx.x.x.xx:xxxx/yyy" db.default.username=xxx db.default.password="xxx" db.default.logSql=true
  • 15. DAO Class public class CompanyRepository { public CompletionStage<Map<String, String>> options() { return supplyAsync(() -> ebeanServer.find(Company.class).orderBy("name").findList(), executionContext).thenApply(list -> { HashMap<String, String> options = new LinkedHashMap<String, String>(); for (Company c : list) { options.put(c.id.toString(), c.getName()); } return options; }); } }
  • 16. Test DAO Class sbt testOnly respository.CompanyRepositoryTest public class CompanyRepositoryTest extends WithApplication { @Test public void options() throws Exception { final CompanyRepository companyRepository = app.injector().instanceOf(CompanyRepository.class); final CompletionStage<Map<String, String>> stage = companyRepository.options(); await().atMost(1, SECONDS).until(() -> assertThat(stage.toCompletableFuture()).isCompletedWithValueMatching(companyMap -> { return companyMap.size() == 42; }) ); } }
  • 17. Controller Class public class HomeController extends Controller { public CompletionStage<Result> edit(Long id) { CompletionStage<Map<String, String>> companiesFuture = companyRepository.options(); return computerRepository.lookup(id).thenCombineAsync(companiesFuture, (computerOptional, companies) -> { Computer c = computerOptional.get(); Form<Computer> computerForm = formFactory.form(Computer.class).fill(c); return ok(views.html.computer.editForm.render(id, computerForm, companies)); }, httpExecutionContext.current()); }
  • 18. Test Controller Class public class HomeControllerTest extends WithApplication { ComputerRepository computerRepository = mock(ComputerRepository.class); @Override protected Application provideApplication() { return new GuiceApplicationBuilder().overrides(bind(ComputerRepository.class).toInstance(computerRe pository)).build(); } @Test public void edit() { final ComputerRepository computerRepository = app.injector().instanceOf(ComputerRepository.class); CompletionStage<Optional<Computer>> computer = CompletableFuture.supplyAsync(()->{ return Optional.of(new Computer()); }); when(computerRepository.lookup(21L)).thenReturn(computer); final CompletionStage<Optional<Computer>> stage = computerRepository.lookup(21L);
  • 19. View template @main("404 - Page Not Found"){ <div class="jumbotron"> <h1>404</h1> <h3>Page Not Found</h3> </div>
  • 20. Test View Template public class Errors_404Test { @Test public void renderTemplate() { HttpExecutionContext httpExecutionContext = app.injector().instanceOf(HttpExecutionContext.class); supplyAsync(()-> { Content html = views.html.errors._404.render(); assertEquals("text/html", html.contentType()); assertTrue(contentAsString(html).contains("Page Not Found")); return 0; }, httpExecutionContext.current()); } }
  • 21. FunctionalTest public class FunctionalTest extends WithApplication { @Test public void redirectHomePage() { Result result = route(app, controllers.routes.HomeController.index()); assertThat(result.status()).isEqualTo(SEE_OTHER); assertThat(result.redirectLocation().get()).isEqualTo("/computers"); } ....
  • 22. Q&A