This document provides an overview of testing for Android applications. It discusses the fundamentals of testing including organizing code for testing, configuring the test environment, and writing different types of tests. Specifically, it covers unit testing Android applications with examples of writing unit tests for applications following the Clean Architecture pattern. It demonstrates how to test different layers including the domain layer with use cases, data layer with mappers and repositories, and remote data sources. The document emphasizes the importance of testing and provides guidance on test organization, environments, and coverage.
1. The document discusses good and bad practices for writing unit tests. It emphasizes that tests should verify the expected behavior, fail clearly when something goes wrong, and use mocks and isolation to focus on the code being tested.
2. Some examples of bad tests shown include tests that don't make assertions or assertions that don't provide useful information on failure. Real objects are also used instead of mocks, obscuring the test.
3. Good practices include using mocks to isolate the code being tested, making sure tests fail clearly when something goes wrong, and focusing tests on expected behavior through clear assertions. Automated testing, fixing broken tests, and mastering testing tools are also emphasized.
Spring Certification Questions and Spring Free test are tests created to demonstrate all the functions of our mock exams. You will be able to access ten full questions and will have ten minutes of time for finishing the test.
There are several components you can interact with when you take our mock exams:
Take a look at the progress bar at the top; it will tell how you are progressing through the exam.
Read the question and select only the answers you think are correct by checking the corresponding check box.
Navigate the spring questions using the "Previous" and "Next" buttons.
Mark the spring questions you wish to review later. All the questions you have marked will be listed on the right in the section "marked questions". You will be able to jump directly to the question from this list.
If you want to take a look at the correct answers for a question, just click the "Solution" button. In the solution section you will be able to check your answers as well as find a full explanation of the question.
Keep an eye on the countdown. This will tell you how much time is remaining. When the countdown expires, the test will be automatically submitted.
Once the test is submitted, the "result" section will expand. Here, you will be able to review all the questions of the test. From here, you can also navigate directly to each question.
This document discusses unit testing in Java. It introduces unit testing and the JUnit framework. It explains how to set up a testing environment in Eclipse and describes best practices for writing unit tests. These include avoiding conditional logic and loops, using descriptive method and assertion names, and separating tests by type. Advantages of unit testing include speed, isolation, safety when refactoring, and serving as documentation. Disadvantages include potential high maintenance costs from unnecessary tests. Similar testing frameworks exist for other languages like C#, C++, and Python.
JEEConf 2017 - The hitchhiker’s guide to Java class reloadingAnton Arhipov
In Java, a typical workflow involves restarting the application (almost) with every class change. For some applications it is not a problem at all, for some – it is a disaster.
From HotSwap to agent-based reloading. In this session, we are going to take a look at the options available for Java class reloading. There is plenty of tools that you can use for this task: rely on standard JVM HotSwap, redesign your application to rely on dynamic class loaders, to comprehend the Zen of OSGi, or to integrate a reloading agent. Every option has its own drawbacks and benefits and we’re going to take a deep dive on the subject.
Finally, there are also the conceptual challenges in reloading Java classes. What to do with the state? What should happen with the static initialisers? What if super class changes? Join this session to gain a better understanding of class reloading technologies and become more productive Java developer.
This document summarizes key concepts related to dependency injection (DI) and the Java Contexts and Dependency Injection (CDI) specification, including:
1. DI allows injecting dependencies into components rather than having components directly instantiate or look up dependencies, improving loose coupling.
2. CDI builds on DI and allows injecting not just dependencies but any object into Java components using the @Inject annotation without requiring XML configuration.
3. Qualifiers like @Named allow disambiguating between multiple implementations of a service when injecting dependencies.
Java 9 introduces modules to the Java programming language and its runtime. Despite this feature being optional, due to the modularization of the standard library existing applications might behave differently when running on a version 9 JVM. Furthermore, because of changes in the runtime, existing libraries and frameworks might not yet correctly process your modularized code. As a result, updating to a Java 9 VM and taking Java 9 into brings its challanges.
This talk discusses the practical implications of module boundaries and analyzes new limitations Java 9 imposes on the reflection API. This talk explains how reflection is used in popular frameworks like Spring and Hibernate and explains why existing applications might break or change their behavior when facing modularized code. Finally, this talk showcases alternatives to now failing Java programming patterns and weights their robustness with regard to the Java releases 10 and upward.
The presenter is an active contributor to open source and helped to migrate many popular Java libraries to supporting Java 9. As a consequence, he as been working with Java 9 for almost two years.
Java Deserialization Vulnerabilities - The Forgotten Bug Class (RuhrSec Edition)CODE WHITE GmbH
This document discusses Java deserialization vulnerabilities and provides an overview of how they work. It notes that many Java technologies rely on serialization which can enable remote code execution if not implemented securely. The document outlines the history of vulnerabilities found, how to find vulnerabilities, and techniques for exploiting them, using examples like the Javassist/Weld gadget. It also summarizes vulnerabilities the speaker's company Code White found, including in products from Symantec, Atlassian, Commvault, and Oracle.
1. The document discusses good and bad practices for writing unit tests. It emphasizes that tests should verify the expected behavior, fail clearly when something goes wrong, and use mocks and isolation to focus on the code being tested.
2. Some examples of bad tests shown include tests that don't make assertions or assertions that don't provide useful information on failure. Real objects are also used instead of mocks, obscuring the test.
3. Good practices include using mocks to isolate the code being tested, making sure tests fail clearly when something goes wrong, and focusing tests on expected behavior through clear assertions. Automated testing, fixing broken tests, and mastering testing tools are also emphasized.
Spring Certification Questions and Spring Free test are tests created to demonstrate all the functions of our mock exams. You will be able to access ten full questions and will have ten minutes of time for finishing the test.
There are several components you can interact with when you take our mock exams:
Take a look at the progress bar at the top; it will tell how you are progressing through the exam.
Read the question and select only the answers you think are correct by checking the corresponding check box.
Navigate the spring questions using the "Previous" and "Next" buttons.
Mark the spring questions you wish to review later. All the questions you have marked will be listed on the right in the section "marked questions". You will be able to jump directly to the question from this list.
If you want to take a look at the correct answers for a question, just click the "Solution" button. In the solution section you will be able to check your answers as well as find a full explanation of the question.
Keep an eye on the countdown. This will tell you how much time is remaining. When the countdown expires, the test will be automatically submitted.
Once the test is submitted, the "result" section will expand. Here, you will be able to review all the questions of the test. From here, you can also navigate directly to each question.
This document discusses unit testing in Java. It introduces unit testing and the JUnit framework. It explains how to set up a testing environment in Eclipse and describes best practices for writing unit tests. These include avoiding conditional logic and loops, using descriptive method and assertion names, and separating tests by type. Advantages of unit testing include speed, isolation, safety when refactoring, and serving as documentation. Disadvantages include potential high maintenance costs from unnecessary tests. Similar testing frameworks exist for other languages like C#, C++, and Python.
JEEConf 2017 - The hitchhiker’s guide to Java class reloadingAnton Arhipov
In Java, a typical workflow involves restarting the application (almost) with every class change. For some applications it is not a problem at all, for some – it is a disaster.
From HotSwap to agent-based reloading. In this session, we are going to take a look at the options available for Java class reloading. There is plenty of tools that you can use for this task: rely on standard JVM HotSwap, redesign your application to rely on dynamic class loaders, to comprehend the Zen of OSGi, or to integrate a reloading agent. Every option has its own drawbacks and benefits and we’re going to take a deep dive on the subject.
Finally, there are also the conceptual challenges in reloading Java classes. What to do with the state? What should happen with the static initialisers? What if super class changes? Join this session to gain a better understanding of class reloading technologies and become more productive Java developer.
This document summarizes key concepts related to dependency injection (DI) and the Java Contexts and Dependency Injection (CDI) specification, including:
1. DI allows injecting dependencies into components rather than having components directly instantiate or look up dependencies, improving loose coupling.
2. CDI builds on DI and allows injecting not just dependencies but any object into Java components using the @Inject annotation without requiring XML configuration.
3. Qualifiers like @Named allow disambiguating between multiple implementations of a service when injecting dependencies.
Java 9 introduces modules to the Java programming language and its runtime. Despite this feature being optional, due to the modularization of the standard library existing applications might behave differently when running on a version 9 JVM. Furthermore, because of changes in the runtime, existing libraries and frameworks might not yet correctly process your modularized code. As a result, updating to a Java 9 VM and taking Java 9 into brings its challanges.
This talk discusses the practical implications of module boundaries and analyzes new limitations Java 9 imposes on the reflection API. This talk explains how reflection is used in popular frameworks like Spring and Hibernate and explains why existing applications might break or change their behavior when facing modularized code. Finally, this talk showcases alternatives to now failing Java programming patterns and weights their robustness with regard to the Java releases 10 and upward.
The presenter is an active contributor to open source and helped to migrate many popular Java libraries to supporting Java 9. As a consequence, he as been working with Java 9 for almost two years.
Java Deserialization Vulnerabilities - The Forgotten Bug Class (RuhrSec Edition)CODE WHITE GmbH
This document discusses Java deserialization vulnerabilities and provides an overview of how they work. It notes that many Java technologies rely on serialization which can enable remote code execution if not implemented securely. The document outlines the history of vulnerabilities found, how to find vulnerabilities, and techniques for exploiting them, using examples like the Javassist/Weld gadget. It also summarizes vulnerabilities the speaker's company Code White found, including in products from Symantec, Atlassian, Commvault, and Oracle.
Surviving the Java Deserialization Apocalypse // OWASP AppSecEU 2016Christian Schneider
The hidden danger of Java deserialization vulnerabilities – which often lead to remote code execution – has gained extended visibility in the past year. The issue has been known for years; however, it seems that the majority of developers were unaware of it until recent media coverage around commonly used libraries and major products. This talk aims to shed some light about how this vulnerability can be abused, how to detect it from a static and dynamic point of view, and -- most importantly -- how to effectively protect against it. The scope of this talk is not limited to the Java serialization protocol but also other popular Java libraries used for object serialization.
The ever-increasing number of new vulnerable endpoints and attacker-usable gadgets has resulted in a lot of different recommendations on how to protect your applications, including look-ahead deserialization and runtime agents to monitor and protect the deserialization process. Coming at the problem from a developer’s perspective and triaging the recommendations for you, this talk will review existing protection techniques and demonstrate their effectiveness on real applications. It will also review existing techniques and present new gadgets that demonstrates how attackers can actually abuse your application code and classpath to craft a chain of gadgets that will allow them to compromise your servers.
This talk will also present the typical architectural decisions and code patterns that lead to an increased risk of exposing deserialization vulnerabilities. Mapping the typical anti-patterns that must be avoided, through the use of real code examples we present an overview of hardening techniques and their effectiveness. The talk will also show attendees what to search the code for in order to find potential code gadgets the attackers can leverage to compromise their applications. We’ll conclude with action items and recommendations developers should consider to mitigate this threat.
--
This talk was presented by Alvaro Muñoz & Christian Schneider at the OWASP AppSecEU 2016 conference in Rome.
Unit testing in iOS featuring OCUnit, GHUnit & OCMockRobot Media
This document provides an overview and introduction to unit testing in iOS. It discusses OCUnit, GHUnit and OCMock, which are common frameworks for unit testing, mock objects, and assertions in Objective-C and iOS. The key points covered include:
- OCUnit is the default unit testing framework for Objective-C, with built-in support in Xcode.
- GHUnit is an alternative open source framework that provides a GUI runner and additional macros.
- OCMock allows mocking objects to control and isolate dependencies in tests.
- Examples are provided of writing tests with OCUnit, GHUnit and using mock objects with OCMock.
- Reasons for unit testing like fixing bugs early and easier
Как надо правильно строить автоматизацию тестирования с нуля, что нужно применять, а то не нужно применять при проектировании архитектуры. Какие виды фреймворков бывают, что с ними надо делать. Все и много другое вы сможете найти в этой презентации
Quality assurance and testing are very important in a life cycle of any application. Although, by far not all developers understand the significance of tests.
In this presentation, we cover the basic testing practices for developers. The following tools are discussed: JUnit, Mockito, Hamcrest, JsTestDriver, DBUnit, Arquillian, SoapUI, Selenium.
This document discusses techniques for improving Android application performance, including:
1. Using static factory methods and object pooling to improve memory management.
2. Configuring applications and services to run in separate processes to improve isolation and increase available memory.
3. Implementing multi-threading correctly using Handlers to schedule work off the UI thread and reduce garbage collection calls.
4. Understanding how to use Android application and activity components like Services and Fragments appropriately.
How Does Kubernetes Build OpenAPI Specifications?reallavalamp
The document discusses how Kubernetes generates OpenAPI specifications from its resource model. It involves a multi-phase process: (1) A code generator compiles Kubernetes API definitions and documentation comments into a Go file defining the OpenAPI schema; (2) At runtime, additional information like supported verbs is added to construct the full specification; (3) Specs can be merged and filtered as needed. The spec is then used to generate clients and for discovery purposes like caching in kubectl. Future work could involve declaring more validation rules and defaults in the resource definitions.
In 2008 Android app code had a lot of boilerplate, and was very error prone.
More code.. more bugs!
Now it doesn't have to be... but that is an option that each developer needs to take!
JMockit is a Java mocking framework that provides tools for isolating code dependencies during unit testing. It uses bytecode instrumentation to remap classes at runtime, allowing final classes and static methods to be mocked. Expectations define mock object behavior, and verifications ensure mocks are used as expected. JMockit provides a more powerful and flexible mocking approach than alternatives like Mockito through its instrumentation and expectations/verifications APIs.
The document discusses JUnit 5, the next generation of the JUnit testing framework for Java. Key aspects include a new programming model using extensions, support for Java 8 features, and ways to migrate from earlier JUnit versions. The new framework consists of the JUnit Platform launcher, the JUnit Jupiter API for writing tests, and the JUnit Vintage engine for running JUnit 3 and 4 tests.
The document discusses unit testing and test-driven development. It introduces the QUnit JavaScript testing framework, describing how to write tests and assertions using its API. Key aspects covered include setting up QUnit, the test and assert functions, asynchronous testing, grouping tests into modules, and integrating automated testing with Node and Grunt.
Java Deserialization Vulnerabilities - The Forgotten Bug ClassCODE WHITE GmbH
This document discusses Java deserialization vulnerabilities. It provides an introduction to how Java serialization works and what the security issues are. Specifically, it describes how an attacker can exploit vulnerabilities to remotely execute code on a server by deserializing malicious objects. The document gives examples of past vulnerabilities found in various Java applications and frameworks. It also provides tips for finding vulnerabilities and generating payloads to demonstrate exploits.
This document provides an overview of tools available in the Java Development Kit (JDK) that allow for powerful introspection and manipulation of the Java Virtual Machine (JVM) and running applications. It discusses the java.lang.instrument API for injecting Java agents, the Java Debugging Interface (JDI) for debugging, the JVM Tool Interface (JVMTI) for heap and frame introspection, and examples of using these tools to build interactive debuggers, inject code at runtime, and test concurrency. Code samples and links to further resources are also provided.
This document discusses Java serialization vulnerabilities and mitigations. It introduces Java serialization, attack vectors like serialization gadgets and deserialization endpoints, and demonstrates denial of service attacks. It covers mitigations such as validating class names during deserialization, but notes this approach can be bypassed. It proposes a new concept of also validating methods during deserialization. The goal is to help fix issues with the Java serialization process.
RelProxy, Easy Class Reload and Scripting with JavaJose María Arranz
Presentation of RelProxy (mainly Java features) in Madrid Java User Group (MadridJUG) on January 28, 2015
Note: original was created with Google Presentations
Bytecode manipulation with Javassist and ASMashleypuls
The document discusses a presentation titled "Living in the Matrix with Bytecode Manipulation". It provides an overview of bytecode and frameworks for manipulating bytecode. Specifically, it discusses what bytecode is, reasons for manipulating bytecode, frameworks for doing so, and examines logging as an example use case. The presentation outlines how to add logging to methods by annotating them and transforming the bytecode at runtime using a Java agent.
Spring Framework Petclinic sample applicationAntoine Rey
Spring Petclinic is a sample application that has been designed to show how the Spring Framework can be used to build simple but powerful database-oriented applications.
The fork named Spring Framework Petclinic maintains a version both with a plain old Spring Framework configuration and a 3-layer architecture (i.e. presentation --> service --> repository).
The document discusses JUnit, a unit testing framework for Java. It provides an example of using JUnit to test a class called StaticCalculation that performs basic math operations like addition and multiplication. The tests check that the operations return the expected values. It also discusses how to create JUnit tests in Eclipse and integrate test cases into source code files.
This document provides an overview of various testing frameworks and concepts used for Android testing. It discusses JUnit, Mockito, PowerMock, Robolectric, and Espresso - the most popular tools for unit, integration, and UI testing of Android apps. For each tool, it provides brief descriptions of their purpose and capabilities. It also includes examples demonstrating how to write tests using JUnit, Mockito, and PowerMock. The document aims to explain what these testing tools are and how they can be used for testing Android applications.
A fresh look at Java Enterprise Application testing with ArquillianVineet Reynolds
This document discusses testing Java enterprise applications with Arquillian. It begins by describing some issues with traditional mocking approaches. It then demonstrates how Arquillian allows testing with real objects by running tests inside a container managed environment. Key aspects of Arquillian include using the @Deployment annotation to package classes and resources, dependency injection of test instances, and running tests without mocks by interacting with real objects. The document concludes by noting how Arquillian changes perspectives on testing and introduces the persistence extension for refining database integration tests.
The document discusses challenges with cross-platform testing of a content management system used at the BBC that runs on both Windows and Unix. It describes using tools like Test::MockObject and Test::MockModule to mock platform-specific functions and GUI components to allow Unix tests to run on Windows. Automating tests on multiple platforms and writing tests in a platform-agnostic way from the start are recommended to improve test coverage across operating systems.
This document discusses test automation for NoSQL databases. It introduces NoSQL Unit, an open source framework for testing persistence layers of NoSQL databases. NoSQL Unit allows loading test data, connecting to databases, and comparing expected and actual data. It supports databases like MongoDB, Cassandra, Elasticsearch and Redis. The document also discusses using Travis CI for continuous integration of NoSQL database tests. Travis CI is a free service that runs builds and tests of GitHub projects. It can be configured using a .travis.yml file to install databases and run tests as part of the build.
Surviving the Java Deserialization Apocalypse // OWASP AppSecEU 2016Christian Schneider
The hidden danger of Java deserialization vulnerabilities – which often lead to remote code execution – has gained extended visibility in the past year. The issue has been known for years; however, it seems that the majority of developers were unaware of it until recent media coverage around commonly used libraries and major products. This talk aims to shed some light about how this vulnerability can be abused, how to detect it from a static and dynamic point of view, and -- most importantly -- how to effectively protect against it. The scope of this talk is not limited to the Java serialization protocol but also other popular Java libraries used for object serialization.
The ever-increasing number of new vulnerable endpoints and attacker-usable gadgets has resulted in a lot of different recommendations on how to protect your applications, including look-ahead deserialization and runtime agents to monitor and protect the deserialization process. Coming at the problem from a developer’s perspective and triaging the recommendations for you, this talk will review existing protection techniques and demonstrate their effectiveness on real applications. It will also review existing techniques and present new gadgets that demonstrates how attackers can actually abuse your application code and classpath to craft a chain of gadgets that will allow them to compromise your servers.
This talk will also present the typical architectural decisions and code patterns that lead to an increased risk of exposing deserialization vulnerabilities. Mapping the typical anti-patterns that must be avoided, through the use of real code examples we present an overview of hardening techniques and their effectiveness. The talk will also show attendees what to search the code for in order to find potential code gadgets the attackers can leverage to compromise their applications. We’ll conclude with action items and recommendations developers should consider to mitigate this threat.
--
This talk was presented by Alvaro Muñoz & Christian Schneider at the OWASP AppSecEU 2016 conference in Rome.
Unit testing in iOS featuring OCUnit, GHUnit & OCMockRobot Media
This document provides an overview and introduction to unit testing in iOS. It discusses OCUnit, GHUnit and OCMock, which are common frameworks for unit testing, mock objects, and assertions in Objective-C and iOS. The key points covered include:
- OCUnit is the default unit testing framework for Objective-C, with built-in support in Xcode.
- GHUnit is an alternative open source framework that provides a GUI runner and additional macros.
- OCMock allows mocking objects to control and isolate dependencies in tests.
- Examples are provided of writing tests with OCUnit, GHUnit and using mock objects with OCMock.
- Reasons for unit testing like fixing bugs early and easier
Как надо правильно строить автоматизацию тестирования с нуля, что нужно применять, а то не нужно применять при проектировании архитектуры. Какие виды фреймворков бывают, что с ними надо делать. Все и много другое вы сможете найти в этой презентации
Quality assurance and testing are very important in a life cycle of any application. Although, by far not all developers understand the significance of tests.
In this presentation, we cover the basic testing practices for developers. The following tools are discussed: JUnit, Mockito, Hamcrest, JsTestDriver, DBUnit, Arquillian, SoapUI, Selenium.
This document discusses techniques for improving Android application performance, including:
1. Using static factory methods and object pooling to improve memory management.
2. Configuring applications and services to run in separate processes to improve isolation and increase available memory.
3. Implementing multi-threading correctly using Handlers to schedule work off the UI thread and reduce garbage collection calls.
4. Understanding how to use Android application and activity components like Services and Fragments appropriately.
How Does Kubernetes Build OpenAPI Specifications?reallavalamp
The document discusses how Kubernetes generates OpenAPI specifications from its resource model. It involves a multi-phase process: (1) A code generator compiles Kubernetes API definitions and documentation comments into a Go file defining the OpenAPI schema; (2) At runtime, additional information like supported verbs is added to construct the full specification; (3) Specs can be merged and filtered as needed. The spec is then used to generate clients and for discovery purposes like caching in kubectl. Future work could involve declaring more validation rules and defaults in the resource definitions.
In 2008 Android app code had a lot of boilerplate, and was very error prone.
More code.. more bugs!
Now it doesn't have to be... but that is an option that each developer needs to take!
JMockit is a Java mocking framework that provides tools for isolating code dependencies during unit testing. It uses bytecode instrumentation to remap classes at runtime, allowing final classes and static methods to be mocked. Expectations define mock object behavior, and verifications ensure mocks are used as expected. JMockit provides a more powerful and flexible mocking approach than alternatives like Mockito through its instrumentation and expectations/verifications APIs.
The document discusses JUnit 5, the next generation of the JUnit testing framework for Java. Key aspects include a new programming model using extensions, support for Java 8 features, and ways to migrate from earlier JUnit versions. The new framework consists of the JUnit Platform launcher, the JUnit Jupiter API for writing tests, and the JUnit Vintage engine for running JUnit 3 and 4 tests.
The document discusses unit testing and test-driven development. It introduces the QUnit JavaScript testing framework, describing how to write tests and assertions using its API. Key aspects covered include setting up QUnit, the test and assert functions, asynchronous testing, grouping tests into modules, and integrating automated testing with Node and Grunt.
Java Deserialization Vulnerabilities - The Forgotten Bug ClassCODE WHITE GmbH
This document discusses Java deserialization vulnerabilities. It provides an introduction to how Java serialization works and what the security issues are. Specifically, it describes how an attacker can exploit vulnerabilities to remotely execute code on a server by deserializing malicious objects. The document gives examples of past vulnerabilities found in various Java applications and frameworks. It also provides tips for finding vulnerabilities and generating payloads to demonstrate exploits.
This document provides an overview of tools available in the Java Development Kit (JDK) that allow for powerful introspection and manipulation of the Java Virtual Machine (JVM) and running applications. It discusses the java.lang.instrument API for injecting Java agents, the Java Debugging Interface (JDI) for debugging, the JVM Tool Interface (JVMTI) for heap and frame introspection, and examples of using these tools to build interactive debuggers, inject code at runtime, and test concurrency. Code samples and links to further resources are also provided.
This document discusses Java serialization vulnerabilities and mitigations. It introduces Java serialization, attack vectors like serialization gadgets and deserialization endpoints, and demonstrates denial of service attacks. It covers mitigations such as validating class names during deserialization, but notes this approach can be bypassed. It proposes a new concept of also validating methods during deserialization. The goal is to help fix issues with the Java serialization process.
RelProxy, Easy Class Reload and Scripting with JavaJose María Arranz
Presentation of RelProxy (mainly Java features) in Madrid Java User Group (MadridJUG) on January 28, 2015
Note: original was created with Google Presentations
Bytecode manipulation with Javassist and ASMashleypuls
The document discusses a presentation titled "Living in the Matrix with Bytecode Manipulation". It provides an overview of bytecode and frameworks for manipulating bytecode. Specifically, it discusses what bytecode is, reasons for manipulating bytecode, frameworks for doing so, and examines logging as an example use case. The presentation outlines how to add logging to methods by annotating them and transforming the bytecode at runtime using a Java agent.
Spring Framework Petclinic sample applicationAntoine Rey
Spring Petclinic is a sample application that has been designed to show how the Spring Framework can be used to build simple but powerful database-oriented applications.
The fork named Spring Framework Petclinic maintains a version both with a plain old Spring Framework configuration and a 3-layer architecture (i.e. presentation --> service --> repository).
The document discusses JUnit, a unit testing framework for Java. It provides an example of using JUnit to test a class called StaticCalculation that performs basic math operations like addition and multiplication. The tests check that the operations return the expected values. It also discusses how to create JUnit tests in Eclipse and integrate test cases into source code files.
This document provides an overview of various testing frameworks and concepts used for Android testing. It discusses JUnit, Mockito, PowerMock, Robolectric, and Espresso - the most popular tools for unit, integration, and UI testing of Android apps. For each tool, it provides brief descriptions of their purpose and capabilities. It also includes examples demonstrating how to write tests using JUnit, Mockito, and PowerMock. The document aims to explain what these testing tools are and how they can be used for testing Android applications.
A fresh look at Java Enterprise Application testing with ArquillianVineet Reynolds
This document discusses testing Java enterprise applications with Arquillian. It begins by describing some issues with traditional mocking approaches. It then demonstrates how Arquillian allows testing with real objects by running tests inside a container managed environment. Key aspects of Arquillian include using the @Deployment annotation to package classes and resources, dependency injection of test instances, and running tests without mocks by interacting with real objects. The document concludes by noting how Arquillian changes perspectives on testing and introduces the persistence extension for refining database integration tests.
The document discusses challenges with cross-platform testing of a content management system used at the BBC that runs on both Windows and Unix. It describes using tools like Test::MockObject and Test::MockModule to mock platform-specific functions and GUI components to allow Unix tests to run on Windows. Automating tests on multiple platforms and writing tests in a platform-agnostic way from the start are recommended to improve test coverage across operating systems.
This document discusses test automation for NoSQL databases. It introduces NoSQL Unit, an open source framework for testing persistence layers of NoSQL databases. NoSQL Unit allows loading test data, connecting to databases, and comparing expected and actual data. It supports databases like MongoDB, Cassandra, Elasticsearch and Redis. The document also discusses using Travis CI for continuous integration of NoSQL database tests. Travis CI is a free service that runs builds and tests of GitHub projects. It can be configured using a .travis.yml file to install databases and run tests as part of the build.
Integration testing is hard, and often teams are tempted to do it in production. Testcontainers allows writing meaningful integration tests spawning Docker containers for databases, queue systems, kv-store, other services. The talk, a blend of slides and live code, will show how we are able to deploy without fear while integrating with a dozen of different datastores. Don't mock your database with fake data anymore, work with real data
This document provides an overview of JUnit 5 and TestContainers. It discusses how JUnit 5 is composed of the JUnit Platform, JUnit Jupiter, and JUnit Vintage modules. It covers JUnit 5 annotations, assertions, assumptions, parameterized and conditional tests. It also discusses how TestContainers allows tests to use live Docker containers as their test environment by launching containers during tests. This includes using generic containers, specialized database containers, and configuring container properties. Resources for further learning about both tools are also provided.
Guide to the jungle of testing frameworksTomáš Kypta
There are many tools, libraries and frameworks available for Android developers to test their applications. The jungle is huge and it's not easy to find the right ones. Some frameworks are good for unit testing, some are good for instrumentation testing, and some can be used for both. Some have great capabilities but annoying weaknesses. Some are good for testing UI, other allow you to make good mocks. We will look at many frameworks, the popular ones like Mockito, Robolectric, Espresso, and some other.
Presented at GDG DevFest Minsk 2016.
Breaking Dependencies to Allow Unit TestingSteven Smith
Unit testing software can be difficult, especially when the software wasn't designed to be testable. Dependencies on infrastructure concerns and software we don't control are one of the biggest contributors to testing difficulty. In this session, you'll learn the difference between unit tests and other kinds of tests, how to recognize and invert dependencies, and how to unit test your code's interactions with these dependencies without testing the infrastructure itself.
Presented at FalafelCON 2014, San Francisco, September 2014
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014FalafelSoftware
Unit testing software can be difficult, especially when the software wasn't designed to be testable. Dependencies on infrastructure concerns and software we don't control are one of the biggest contributors to testing difficulty. In this session, you'll learn the difference between unit tests and other kinds of tests, how to recognize and invert dependencies, and how to unit test your code's interactions with these dependencies without testing the infrastructure itself.
Oh so you test? - A guide to testing on Android from Unit to MutationPaul Blundell
Everyone knows you need testing, but what are the different types of testing, how will each type benefit you and what libraries are available to ease the pain? This talk will run through an explanation of each type of testing (unit, integration, functional, acceptance, fuzz, mutation...) explaining upon each level of an Android app, the testing involved, how this will benefit you and how it will benefit your users. It will also explain the architecture of a well tested app. Finally ending with some examples and libraries that ease your accessibility into testing and help with faster more descriptive feedback.
This document introduces Test Driven Development (TDD) for MapReduce jobs using the MRUnit testing framework. It discusses how TDD is difficult for Hadoop due to its distributed nature but can be achieved by abstracting business logic. It provides examples of using MRUnit to test mappers, reducers and full MapReduce jobs. It also discusses testing with real data by loading samples into the local filesystem or using a WindowsLocalFileSystem class to enable permission testing on Windows.
This presentation introduces PHP unit testing in Yii. It covers test-driven development (TDD) principles, the different types of tests like unit tests and integration tests, how to set up PHPUnit and write tests in Yii, using fixtures to test database interactions, and invoking tests from the command line. Examples are provided of writing unit tests for models and using fixtures to load test data.
This document discusses testability and provides lessons learned around testability. It begins with an introduction of the speaker and their background in testing. It then outlines some common testability problems like statics, singletons, and tight coupling. Solutions discussed include dependency injection and using mocks/fakes to isolate units for testing. The document provides an example of refactoring a weather application to make it more testable and enables the use of mocks for testing.
The document discusses unit testing in Grails using the Spock testing framework. It covers the basics of unit testing including goals, advantages, and challenges. It then provides an overview of Spock and examples of writing unit tests in Spock including mocking methods, domains, configurations, and dependencies. The document also discusses how to write unit tests for controllers and integration tests in Grails using Spock.
Automated integration tests for ajax applications (с. карпушин, auriga)Mobile Developer Day
The document discusses automated integration tests for AJAX applications. It covers motivations like reliability and reducing bug time. Challenges include asynchronous behavior and lack of tools. Solutions presented are Selenium and jWebUnit for testing, as well as configuring continuous integration. Experience shows a project spending less time on manual testing after implementing automated tests.
Unit Testing on Android involves testing individual units or components of code to find and fix bugs early. There are several test frameworks for Android like JUnit and Mockito that make unit testing easier. JUnit provides annotations to mark test methods and assertions to validate results. Mockito allows mocking dependencies to isolate and focus on the code being tested. Robolectric runs tests directly on a JVM without needing an emulator for faster testing. Code coverage tools like JaCoCo measure how much code is executed during tests.
This document discusses testing applications on Google App Engine. It covers using the App Engine testing framework to test the local datastore, authentication API, and memcache. It also provides an overview of Google Cloud Cover, which allows running test suites in parallel on the cloud. The document includes code examples for setting up local testing of the datastore using Spring and JUnit and testing the authentication API and memcache. It emphasizes that testing is important for correctness and refactoring and that App Engine has specific testing strategies to test core services locally.
Guide to the jungle of testing frameworksTomáš Kypta
There are many tools, libraries and frameworks available for Android developers to test their applications. The jungle is huge and it's not easy to find the right ones. Some frameworks are good for unit testing, some are good for instrumentation testing, and some can be used for both. Some have great capabilities but annoying weaknesses. Some are good for testing UI, other allow you to make good mocks. We will look at many frameworks, the popular ones like Mockito, Robolectric, Espresso, and some other.
Presented at GDG DevFest Pilsen 2016.
The document discusses Agile testing techniques for Swift including unit testing with XCTest and GUI testing with XCUI. It provides details on mocking with Cuckoo, API testing with Postman, integrating tests with Jenkins, and measuring quality with SonarQube. Sample code is shown for unit tests, API tests, and GUI tests of a sample ETAMock app. Continuous integration with Jenkins and SonarQube is demonstrated along with links for further information.
The document discusses unit testing and provides examples of writing unit tests in PHP using the PHPUnit framework. It explains what unit tests are, why they are useful for finding and preventing bugs, and different types of tests. It also demonstrates how to write tests for a "slugify" string method, use data providers to reduce duplicated code, and mock objects to test code in isolation without external dependencies like databases. The document advocates for test-driven development by writing tests before code. It also mentions how to integrate tests with version control using hooks and generate code coverage reports.
2. Table of contents
- What’s Android testing?
- Fundamentals of Testing
- Unit tests
- Write unit tests for Clean Architecture
- Test coverage
- References
2
3. What’s Android testing?
- It’s a part of the app development process.
- Verify your app's correctness, functional behavior, and usability
before you release it publicly.
- Rapid feedback on failures.
- Early failure detection in the development cycle.
- Safer code refactoring, letting you optimize code without worrying about regressions.
- Stable development velocity, helping you minimize technical debt.
3
4. Fundamentals of Testing
- Organize your code for testing
- Configure your test environment
- Write your tests
4
5. Fundamentals of Testing →
Organize your code for testing
- Create and test code iteratively
5
6. Fundamentals of Testing →
Organize your code for testing
- View your app as a series of modules
6
7. Fundamentals of Testing →
Configure your test environment
- Organize test directories based on execution environment
- androidTest: Directory should contain the tests that run on real or virtual devices.
- Integration tests
- End-to-end tests
- Other tests where the JVM alone cannot validate
- test: Should contain the tests that run on your local machine.
- Unit tests
7
8. Fundamentals of Testing →
Configure your test environment
- Consider tradeoffs of running tests on different types of devices
- Real device
- Virtual device (such as the emulator in Android Studio)
- Simulated device (such as Robolectric)
8
9. Fundamentals of Testing →
Configure your test environment
- Consider whether to use test doubles
Real objects or Test doubles
Test doubles:
- Mock object
- Fake object
- Dummy object
- Test stub
- Test spy
9
10. Fundamentals of Testing →
Write your tests
- Small tests → unit tests
- Medium tests → integration tests
- Large tests → end-to-end tests
10% large
20% medium
70% small
10
11. Unit tests
- What’s unit tests?
- Types of unit tests:
- Local tests
- Instrumented tests
- Libraries support
11
12. Unit tests →
What’s unit tests?
- Unit tests are the fundamental tests
- Easily verify that the logic of individual units
is correct
- Running UTs after every build helps you to
quickly catch and fix.
12
13. Unit tests →
Types of unit tests
Local tests:
- Run on the local machine only.
- Compiled to run locally on JVM to minimize execution time.
- Depend on your own dependencies → using mock objects to emulate
the dependencies' behavior.
13
14. Unit tests →
Types of unit tests
Instrumented tests:
- Run on an Android device or emulator.
- Access to instrumentation information (such as the Context)
- Run unit tests that have complex Android dependencies that require a
more robust environment, such as Robolectric.
14
15. Unit tests →
Libraries support
- JUnit4 or JUnit5
- Mockito (or its Kotlin version mockito-kotlin)
- Mockk
- Robolectric
- AndroidJUnit4
15
16. Write unit tests for Clean Architecture
- Domain
- Use cases
- DI module
- Data
- Mapper
- Repository
- Remote
- Local
- DI module
- Presentation
- Mapper
- View Model
- DI Module
16
17. Write unit tests for Clean Architecture
- Domain
- Use cases
- DI module
17
18. Write unit tests for Clean Architecture → Domain →
Use cases
18
class GetTopUsersUseCase(
private val homeRepository: HomeRepository
) : UseCase<UseCaseParams.Empty, List<UserEntity>>() {
override suspend fun executeInternal(
params: UseCaseParams.Empty
): Either<Failure, List<UserEntity>> {
return homeRepository.getTopUsers()
}
}
19. Write unit tests for Clean Architecture → Domain →
Use cases Test success
19
@RunWith(JUnit4::class)
class GetTopUsersUseCaseTest {
private val repository = mockk<HomeRepository>()
private val useCase = GetTopUsersUseCase(repository)
@Test
fun executeInternal_success() = runBlocking {
val expected = provideUserEntityList()
coEvery { repository.getTopUsers() } returns Either.Success(expected)
useCase.execute(UseCaseParams.Empty).either(
failAction = { assertTrue(false) },
successAction = { actual -> assertEquals(expected, actual) }
)
}
}
20. Write unit tests for Clean Architecture → Domain →
Use cases Test error
20
@RunWith(JUnit4::class)
class GetTopUsersUseCaseTest {
private val repository = mockk<HomeRepository>()
private val useCase = GetTopUsersUseCase(repository)
@Test
fun executeInternal_error() = runBlocking {
val expected = provideFailEither()
coEvery { repository.getTopUsers() } returns expected
useCase.execute(UseCaseParams.Empty).either(
failAction = { actual -> assertEquals(actual, expected) },
successAction = { assertTrue(false) }
)
}
}
21. Write unit tests for Clean Architecture → Domain →
DI modules
21
val createDomainModule = module {
factory { GetTopUsersUseCase(homeRepository = get()) }
factory { GetUserDetailUseCase(detailRepository = get()) }
}
22. Write unit tests for Clean Architecture → Domain →
DI modules Test
22
@Category(CheckModuleTest::class)
class DomainModuleTest : AutoCloseKoinTest() {
@Test
fun checkModules() = checkModules {
val mockModule = module {
factory { mockk<HomeRepository>() }
factory { mockk<UserDetailRepository>() }
}
modules(createDomainModule, mockModule)
}
}
23. Write unit tests for Clean Architecture
- Data
- Mapper
- Repository
- Remote
- Local
- DI module
23
24. Write unit tests for Clean Architecture → Data→
Mapper
24
class UserRemoteEntityMapper : Mapper<UserResponse, UserEntity>() {
override fun map(input: UserResponse): UserEntity = UserEntity(
id = input.id.defaultEmpty(),
login = input.login.defaultEmpty(),
avatarUrl = input.avatarUrl.defaultEmpty(),
name = input.name.defaultEmpty(),
company = input.company.defaultEmpty(),
blog = input.blog.defaultEmpty(),
lastRefreshed = Date()
)
}
25. Write unit tests for Clean Architecture → Data→
Mapper Test
25
class UserRemoteEntityMapperTest {
private val userRemoteEntityMapper = UserRemoteEntityMapper()
@Test
fun map() {
val userResponse = provideUserResponse()
val actual = userRemoteEntityMapper.map(userResponse)
val expected = provideUserEntity().copy(lastRefreshed = actual.lastRefreshed)
assertEquals(expected, actual)
}
}
26. Write unit tests for Clean Architecture → Data→
Repository
26
class HomeRepositoryImpl(
private val userDataSource: UserDataSource,
private val userDao: UserDao,
private val remoteExceptionInterceptor: RemoteExceptionInterceptor,
private val userLocalEntityMapper: UserLocalEntityMapper,
private val userResponseLocalMapper: UserResponseLocalMapper
) : HomeRepository {
override suspend fun getTopUsers(): Either<Failure, List<UserEntity>> =
Either.runSuspendWithCatchError(errorInterceptors = listOf(remoteExceptionInterceptor)) {
val dbResult = userLocalEntityMapper.mapList(userDao.getTopUsers())
if (dbResult.isNullOrEmpty()) {
val response = userDataSource.fetchTopUsersAsync()
val userDBOs = userResponseLocalMapper.mapList(response.items)
userDao.insertUses(userDBOs)
val dbAfterInsert = userLocalEntityMapper.mapList(userDao.getTopUsers())
return@runSuspendWithCatchError Either.Success(dbAfterInsert)
} else {
return@runSuspendWithCatchError Either.Success(dbResult)
}
}
}
27. Write unit tests for Clean Architecture → Data→
Repository Mocking
27
class HomeRepositoryImplTest {
private val userDataSource: UserDataSource = mockk()
private val userDao: UserDao = mockk()
private val remoteInterceptor: RemoteExceptionInterceptor = mockk()
private val userLocalEntityMapper: UserLocalEntityMapper = mockk()
private val userResponseLocalMapper: UserResponseLocalMapper = mockk()
private val detailRepositoryImpl = HomeRepositoryImpl(
userDataSource = userDataSource,
userDao = userDao,
remoteExceptionInterceptor = remoteInterceptor,
userLocalEntityMapper = userLocalEntityMapper,
userResponseLocalMapper = userResponseLocalMapper
)
//...
}
28. Write unit tests for Clean Architecture → Data→
Repository Test success from remote
28
class HomeRepositoryImplTest {
// ...
@Test
fun getTopUsers_success_fromRemote() = runBlocking {
val userResponseList = provideUserResponseList()
val userDBOList = provideUserDBOList()
val expected = provideUserEntityList()
val userEntity = provideUserEntity()
coEvery { userDao.getTopUsers() } returnsMany listOf(listOf(), userDBOList)
coEvery { userDataSource.fetchTopUsersAsync() } returns userResponseList
coEvery { userDao.insertUses(userDBOList) } returns Unit
every { userLocalEntityMapper.mapList(listOf()) } returns listOf()
every { userResponseLocalMapper.mapList(userResponseList.items) } returns userDBOList
every { userLocalEntityMapper.mapList(userDBOList) } returns expected
detailRepositoryImpl.getTopUsers().either(
failAction = { assertTrue(false) },
successAction = { actual ->
assertEquals(expected, actual)
}
)
}
}
29. Write unit tests for Clean Architecture → Data→
Repository Test error
29
class HomeRepositoryImplTest {
@Test
fun getTopUsers_error() = runBlocking {
val exception = provideException()
coEvery { userDao.getTopUsers() } returns listOf()
coEvery { userDataSource.fetchTopUsersAsync() } throws exception
every { userLocalEntityMapper.mapList(listOf()) } returns listOf()
every {
remoteInterceptor.handleException(exception)
} returns Failure.UnCatchError(exception)
detailRepositoryImpl.getTopUsers().either(
failAction = { assertTrue(true) },
successAction = { assertTrue(false) }
)
}
}
30. Write unit tests for Clean Architecture
- Data
- Mapper
- Repository implemented
- Remote
- Local
- DI module
30
31. Write unit tests for Clean Architecture → Data→ Remote
UserDataSource
31
class UserDataSource(private val userService: UserService) {
suspend fun fetchTopUsersAsync() = userService.fetchTopUsersAsync()
}
32. Write unit tests for Clean Architecture → Data→ Remote
UserDataSource Test
32
class UserDataSourceTest {
private val userService: UserService = mockk()
private val userDataSource = UserDataSource(userService)
@Test
fun fetchTopUsersAsync() = runBlocking {
val expected = provideUserResponseList()
coEvery { userService.fetchTopUsersAsync() } returns expected
val actual = userDataSource.fetchTopUsersAsync()
Assert.assertEquals(expected, actual)
}
}
34. Write unit tests for Clean Architecture → Data→ Remote
UserService Test
34
open class UserServiceTest() {
private lateinit var mockServer: MockWebServer
protected val userDataSource: UserDataSource by inject()
@Before
fun setup() {
mockServer = MockWebServer()
mockServer.start()
startKoin { modules(listOf(createRemoteModule(mockServer.url("/").toString()))) }
}
@After
fun tearDown() {
mockServer.shutdown()
stopKoin()
}
}
35. Write unit tests for Clean Architecture → Data→ Remote
UserService Test
35
class UserServiceTest() : AutoCloseKoinTest() {
@Test
fun fetchTopUsersAsync_success() {
mockServer.enqueue(
MockResponse()
.setResponseCode(HttpURLConnection.HTTP_OK)
.setBody(getJson("search_users.json"))
)
runBlocking {
val users = userDataSource.fetchTopUsersAsync()
assertEquals(1, users.items.size)
assertEquals("6847959", users.items.first().id)
assertEquals("PhilippeBoisney", users.items.first().login)
assertEquals(
"https://avatars0.githubusercontent.com/u/6847959?v=4",
users.items.first().avatarUrl
)
}
}
}
36. Write unit tests for Clean Architecture
- Data
- Mapper
- Repository
- Remote
- Local
- DI module
36
37. Write unit tests for Clean Architecture → Data→ Local
Room DAO
37
@Dao
interface UserDao {
@Insert
suspend fun insertUses(userDBOS: List<UserDBO>)
@Query("SELECT * FROM UserDBO ORDER BY login ASC LIMIT 30")
suspend fun getTopUsers(): List<UserDBO>
}
38. Write unit tests for Clean Architecture → Data→ Local
Room DAO Test
38
@RunWith(AndroidJUnit4::class)
@ExperimentalCoroutinesApi
class UserDaoTest {
private lateinit var userDao: UserDao
private lateinit var database: MulAppDatabase
private val testDispatcher = TestCoroutineDispatcher()
private val testScope = TestCoroutineScope(testDispatcher)
@Before
fun setup() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
database = Room.inMemoryDatabaseBuilder(context, MulAppDatabase::class.java)
.setTransactionExecutor(testDispatcher.asExecutor())
.setQueryExecutor(testDispatcher.asExecutor())
.build()
userDao = database.userDao()
}
@After
@Throws(IOException::class)
fun clear() {
database.close()
}
}
39. Write unit tests for Clean Architecture → Data→ Local
Room DAO Test
39
@RunWith(AndroidJUnit4::class)
@ExperimentalCoroutinesApi
class UserDaoTest {
// ...
@Test
fun test_insertUsers() = testScope.runBlockingTest {
val expected = provideUserDBOList(10)
userDao.insertUses(expected)
val actual = userDao.getTopUsers()
Assert.assertEquals(expected, actual)
}
}
40. Write unit tests for Clean Architecture
- Presentation
- Mapper
- View Model
- DI module
40
41. Write unit tests for Clean Architecture → Presentation →
ViewModel
41
class HomeViewModel(
private val getTopUsersUseCase: GetTopUsersUseCase,
private val appDispatchers: AppDispatchers
) : BaseViewModel() {
val usersLiveData: MutableLiveData<List<UserEntity>> = MutableLiveData()
val isLoading: MutableLiveData<Boolean> = MutableLiveData()
fun loadUsers() = viewModelScope.launch(appDispatchers.main) {
isLoading.value = true
val getUserResult = getTopUsersUseCase.execute(UseCaseParams.Empty)
isLoading.value = false
getUserResult.either(
failAction = {
usersLiveData.value = null
},
successAction = { userEntities ->
usersLiveData.value = userEntities
}
)
}
}
42. Write unit tests for Clean Architecture → Presentation →
ViewModel Mocking
42
@ExperimentalCoroutinesApi
class HomViewModelTest {
@Rule
@JvmField
val instantTaskExecutorRule = InstantTaskExecutorRule()
private val getTopUsersUseCase = mockk<GetTopUsersUseCase>()
private val appDispatchers = AppDispatchers(TestCoroutineDispatcher(), TestCoroutineDispatcher())
private val homeViewModel = HomeViewModel(getTopUsersUseCase, appDispatchers)
// ...
}
43. Write unit tests for Clean Architecture → Presentation →
ViewModel Test
43
@ExperimentalCoroutinesApi
class HomeViewModelTest {
// ...
@Test
fun loadUsers_success() {
val expectedUsers = provideUserEntityList()
val observerUsers: Observer<List<UserEntity>> = mockk(relaxed = true)
val observerLoading: Observer<Boolean> = mockk(relaxed = true)
coEvery { getTopUsersUseCase.execute(UseCaseParams.Empty) } returns Either.Success(expectedUsers)
homeViewModel.usersLiveData.observeForever(observerUsers)
homeViewModel.isLoading.observeForever(observerLoading)
homeViewModel.loadUsers()
verify {
observerUsers.onChanged(expectedUsers)
}
verifySequence {
observerLoading.onChanged(true)
observerLoading.onChanged(false)
}
confirmVerified(observerUsers)
}
}
44. Write unit tests for Clean Architecture → Presentation → ViewModel Test →
Relaxed
44
class Divider() {
fun divide(p1: Int, p2: Int): Float {
return p1.toFloat() / p2
}
}
class Calculator(val div: Divider) {
fun executeDivide(p1: Int, p2: Int): Float {
return div.divide(p1, p2)
}
}
@Test
fun divTest() {
val mockDiv = mockk<Divider>(relaxed = true)
val cal = Calculator(div = mockDiv)
cal.executeDivide(1, 2)
verify { mockDiv.divide(1, 2) }
}
--------------------------------------------------------
@Test
fun divTest() {
val mockDiv = mockk<Divider>(relaxed = false)
every { mockDiv.divide(1, 2) } returns 0.5f
val cal = Calculator(div = mockDiv)
cal.executeDivide(1, 2)
verify { mockDiv.divide(1, 2) }
}
46. Test coverage →
Run code coverage in Android Studio
46
Navigate to the src/test/java folder
→ Right click
→ Select Run ‘Tests in ‘com’’ with Coverage
49. References
1. Test apps on Android
2. A guide to test pyramid in Android — Part 1
3. GithubBrowserSample on GitHub
4. MVP Clean Architecture in Tiendeo app
5. Unit test pull request from NHN-base source
49