Given that the database, as the canonical repository of data, is the most important part of many applications, why is it that we don't write database unit tests? This talk promotes the practice of implementing tests to directly test the schema, storage, and functionality of databases.
Given that the database, as the canonical repository of data, is the most important part of many applications, why is it that we don't write database unit tests? This talk promotes the practice of implementing tests to directly test the schema, storage, and functionality of databases.
So you've got testing religion, but the question now is, how do you test your database?
This tutorial introduces pgTAP, a comprehensive, easy-to-use test suite for PostgreSQL. We'll work from getting and installing pgTAP, to writing a simple test, to running the test and integrating it into your test environment. And then we really get into the fun stuff:
Testing scalar values
Testing error conditions and performance regressions
Testing database schemas, including tables, columns, constraints, indexes, triggers, etc.
Testing result sets
Testing procedures
Testing may sound like a dry topic, but my examples aren't! Come join the fun!
This is the support of a course to teach React programming for Java and C# programmers. It covers from its origins in Facebook til separation of presentational and container components. What is JSX, rules, state, props, refactoring, conditionals, repeats, forms, synchronizing values, composition, and so on.
Developer testing 101: Become a Testing FanaticLB Denker
In this workshop we will cover the methodologies and three basic levels of testing, then we will deep dive into how to use PHPUnit to achieve developer testing. The tests may not be the prettiest, most robust, or efficient, but you should leave the course with the ability and confidence to write tests for your code.
Topics include: xUnit framework basics and workflows, test classification, asserts, data driven testing, and an introduction to mocking.
This is a beginner course, but seasoned veterans may discover features they never knew.
How Testability Inspires AngularJS Design / Ran MizrahiRan Mizrahi
Testability is a major part of design decision making in Angular`s development.
In this sessions we’ll cover what testability is, how it inspires Angular`s design and why it’s good for us.
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...GeeksLab Odessa
5.12.15 QA Lab: тестирование программного обеспечения.
Upcoming events: goo.gl/I2gJ4H
Доклад о Play-Swagger, проекте с открытым исходным кодом, разрабатываемом в Zalando с использованием Scala и Play Framework. О том, как использование API First и Swagger позволяет ускорить процесс разработки, упростить взаимодействие команд и повысить качество продукта.
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.
5.12.15 QA Lab: тестирование ПО.
Upcoming events: goo.gl/I2gJ4H
Доклад о популярных и/или лучших практиках в веб-автоматизации с точки зрения принципа KISS. Мы быстро пробежимся и оставим след в следующих темах и технологиях: Selenium, обертки вокруг Selenium, xUnit, BDD, длинные и не очень - End to End сценарии, маленькие независимые тесты Unit стиля, простые или красивые репорты, Allure репортинг, PageObject, виджеты-элементы, парадигмы программирования для автоматизации - ООП, процедурное и модульное.
Unit testing without Robolectric, Droidcon Berlin 2016Danny Preussler
Are you bound to flaky, slow Robolectric Tests? Do you want to know a way out of it? This session shows ideas and concepts to replace Robolectric from your test code base
Lambda Chops - Recipes for Simpler, More Expressive CodeIan Robertson
While the new Streams API has been a great showcase for lambda methods, there are many other ways this new language feature can be used to make friendlier APIs and more expressive code. Lambdas can be used for a number of tasks which historically required significant boilerplate, type-unsafe constructs, or both. From new ways to express metedata, to emulating Groovy's null-safe navigation operator, we'll take a look at a myriad of ways, big and small, that you can use lambdas to improve APIs and streamline your code. We'll also look at some of the limitations of lambdas, and some techniques for overcoming them.
So you've got testing religion, but the question now is, how do you test your database?
This tutorial introduces pgTAP, a comprehensive, easy-to-use test suite for PostgreSQL. We'll work from getting and installing pgTAP, to writing a simple test, to running the test and integrating it into your test environment. And then we really get into the fun stuff:
Testing scalar values
Testing error conditions and performance regressions
Testing database schemas, including tables, columns, constraints, indexes, triggers, etc.
Testing result sets
Testing procedures
Testing may sound like a dry topic, but my examples aren't! Come join the fun!
This is the support of a course to teach React programming for Java and C# programmers. It covers from its origins in Facebook til separation of presentational and container components. What is JSX, rules, state, props, refactoring, conditionals, repeats, forms, synchronizing values, composition, and so on.
Developer testing 101: Become a Testing FanaticLB Denker
In this workshop we will cover the methodologies and three basic levels of testing, then we will deep dive into how to use PHPUnit to achieve developer testing. The tests may not be the prettiest, most robust, or efficient, but you should leave the course with the ability and confidence to write tests for your code.
Topics include: xUnit framework basics and workflows, test classification, asserts, data driven testing, and an introduction to mocking.
This is a beginner course, but seasoned veterans may discover features they never knew.
How Testability Inspires AngularJS Design / Ran MizrahiRan Mizrahi
Testability is a major part of design decision making in Angular`s development.
In this sessions we’ll cover what testability is, how it inspires Angular`s design and why it’s good for us.
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...GeeksLab Odessa
5.12.15 QA Lab: тестирование программного обеспечения.
Upcoming events: goo.gl/I2gJ4H
Доклад о Play-Swagger, проекте с открытым исходным кодом, разрабатываемом в Zalando с использованием Scala и Play Framework. О том, как использование API First и Swagger позволяет ускорить процесс разработки, упростить взаимодействие команд и повысить качество продукта.
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.
5.12.15 QA Lab: тестирование ПО.
Upcoming events: goo.gl/I2gJ4H
Доклад о популярных и/или лучших практиках в веб-автоматизации с точки зрения принципа KISS. Мы быстро пробежимся и оставим след в следующих темах и технологиях: Selenium, обертки вокруг Selenium, xUnit, BDD, длинные и не очень - End to End сценарии, маленькие независимые тесты Unit стиля, простые или красивые репорты, Allure репортинг, PageObject, виджеты-элементы, парадигмы программирования для автоматизации - ООП, процедурное и модульное.
Unit testing without Robolectric, Droidcon Berlin 2016Danny Preussler
Are you bound to flaky, slow Robolectric Tests? Do you want to know a way out of it? This session shows ideas and concepts to replace Robolectric from your test code base
Lambda Chops - Recipes for Simpler, More Expressive CodeIan Robertson
While the new Streams API has been a great showcase for lambda methods, there are many other ways this new language feature can be used to make friendlier APIs and more expressive code. Lambdas can be used for a number of tasks which historically required significant boilerplate, type-unsafe constructs, or both. From new ways to express metedata, to emulating Groovy's null-safe navigation operator, we'll take a look at a myriad of ways, big and small, that you can use lambdas to improve APIs and streamline your code. We'll also look at some of the limitations of lambdas, and some techniques for overcoming them.
This webinar by Oleksandr Navka (Lead Software Engineer, Consultant, GlobalLogic) was delivered at Java Community Webinar #1 on August 12, 2020.
Webinar agenda:
- The new structural unit of the program is Java Records
- Updated instanceof statement
- Updated switch operator
More details and presentation: https://www.globallogic.com/ua/about/events/java-community-webinar-1/
Introduction to functional idioms in Java 8, language-extending functional libraries and short overview of reasons for adoption of such programming style.
Examples and snippets available here: https://github.com/lbialy/functionaljava8
Mastering Mock Objects - Advanced Unit Testing for JavaDenilson Nastacio
A high-level description of mock testing techniques and their implementation for the Java programming language.
This presentation specifically focus on the JMockit and JMock frameworks.
Developing Distributed High-performance Computing Capabilities of an Open Sci...Globus
COVID-19 had an unprecedented impact on scientific collaboration. The pandemic and its broad response from the scientific community has forged new relationships among public health practitioners, mathematical modelers, and scientific computing specialists, while revealing critical gaps in exploiting advanced computing systems to support urgent decision making. Informed by our team’s work in applying high-performance computing in support of public health decision makers during the COVID-19 pandemic, we present how Globus technologies are enabling the development of an open science platform for robust epidemic analysis, with the goal of collaborative, secure, distributed, on-demand, and fast time-to-solution analyses to support public health.
Unleash Unlimited Potential with One-Time Purchase
BoxLang is more than just a language; it's a community. By choosing a Visionary License, you're not just investing in your success, you're actively contributing to the ongoing development and support of BoxLang.
Navigating the Metaverse: A Journey into Virtual Evolution"Donna Lenk
Join us for an exploration of the Metaverse's evolution, where innovation meets imagination. Discover new dimensions of virtual events, engage with thought-provoking discussions, and witness the transformative power of digital realms."
top nidhi software solution freedownloadvrstrong314
This presentation emphasizes the importance of data security and legal compliance for Nidhi companies in India. It highlights how online Nidhi software solutions, like Vector Nidhi Software, offer advanced features tailored to these needs. Key aspects include encryption, access controls, and audit trails to ensure data security. The software complies with regulatory guidelines from the MCA and RBI and adheres to Nidhi Rules, 2014. With customizable, user-friendly interfaces and real-time features, these Nidhi software solutions enhance efficiency, support growth, and provide exceptional member services. The presentation concludes with contact information for further inquiries.
May Marketo Masterclass, London MUG May 22 2024.pdfAdele Miller
Can't make Adobe Summit in Vegas? No sweat because the EMEA Marketo Engage Champions are coming to London to share their Summit sessions, insights and more!
This is a MUG with a twist you don't want to miss.
How Recreation Management Software Can Streamline Your Operations.pptxwottaspaceseo
Recreation management software streamlines operations by automating key tasks such as scheduling, registration, and payment processing, reducing manual workload and errors. It provides centralized management of facilities, classes, and events, ensuring efficient resource allocation and facility usage. The software offers user-friendly online portals for easy access to bookings and program information, enhancing customer experience. Real-time reporting and data analytics deliver insights into attendance and preferences, aiding in strategic decision-making. Additionally, effective communication tools keep participants and staff informed with timely updates. Overall, recreation management software enhances efficiency, improves service delivery, and boosts customer satisfaction.
First Steps with Globus Compute Multi-User EndpointsGlobus
In this presentation we will share our experiences around getting started with the Globus Compute multi-user endpoint. Working with the Pharmacology group at the University of Auckland, we have previously written an application using Globus Compute that can offload computationally expensive steps in the researcher's workflows, which they wish to manage from their familiar Windows environments, onto the NeSI (New Zealand eScience Infrastructure) cluster. Some of the challenges we have encountered were that each researcher had to set up and manage their own single-user globus compute endpoint and that the workloads had varying resource requirements (CPUs, memory and wall time) between different runs. We hope that the multi-user endpoint will help to address these challenges and share an update on our progress here.
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisGlobus
JASMIN is the UK’s high-performance data analysis platform for environmental science, operated by STFC on behalf of the UK Natural Environment Research Council (NERC). In addition to its role in hosting the CEDA Archive (NERC’s long-term repository for climate, atmospheric science & Earth observation data in the UK), JASMIN provides a collaborative platform to a community of around 2,000 scientists in the UK and beyond, providing nearly 400 environmental science projects with working space, compute resources and tools to facilitate their work. High-performance data transfer into and out of JASMIN has always been a key feature, with many scientists bringing model outputs from supercomputers elsewhere in the UK, to analyse against observational or other model data in the CEDA Archive. A growing number of JASMIN users are now realising the benefits of using the Globus service to provide reliable and efficient data movement and other tasks in this and other contexts. Further use cases involve long-distance (intercontinental) transfers to and from JASMIN, and collecting results from a mobile atmospheric radar system, pushing data to JASMIN via a lightweight Globus deployment. We provide details of how Globus fits into our current infrastructure, our experience of the recent migration to GCSv5.4, and of our interest in developing use of the wider ecosystem of Globus services for the benefit of our user community.
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfJay Das
With the advent of artificial intelligence or AI tools, project management processes are undergoing a transformative shift. By using tools like ChatGPT, and Bard organizations can empower their leaders and managers to plan, execute, and monitor projects more effectively.
A Comprehensive Look at Generative AI in Retail App Testing.pdfkalichargn70th171
Traditional software testing methods are being challenged in retail, where customer expectations and technological advancements continually shape the landscape. Enter generative AI—a transformative subset of artificial intelligence technologies poised to revolutionize software testing.
Understanding Globus Data Transfers with NetSageGlobus
NetSage is an open privacy-aware network measurement, analysis, and visualization service designed to help end-users visualize and reason about large data transfers. NetSage traditionally has used a combination of passive measurements, including SNMP and flow data, as well as active measurements, mainly perfSONAR, to provide longitudinal network performance data visualization. It has been deployed by dozens of networks world wide, and is supported domestically by the Engagement and Performance Operations Center (EPOC), NSF #2328479. We have recently expanded the NetSage data sources to include logs for Globus data transfers, following the same privacy-preserving approach as for Flow data. Using the logs for the Texas Advanced Computing Center (TACC) as an example, this talk will walk through several different example use cases that NetSage can answer, including: Who is using Globus to share data with my institution, and what kind of performance are they able to achieve? How many transfers has Globus supported for us? Which sites are we sharing the most data with, and how is that changing over time? How is my site using Globus to move data internally, and what kind of performance do we see for those transfers? What percentage of data transfers at my institution used Globus, and how did the overall data transfer performance compare to the Globus users?
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTier1 app
Even though at surface level ‘java.lang.OutOfMemoryError’ appears as one single error; underlyingly there are 9 types of OutOfMemoryError. Each type of OutOfMemoryError has different causes, diagnosis approaches and solutions. This session equips you with the knowledge, tools, and techniques needed to troubleshoot and conquer OutOfMemoryError in all its forms, ensuring smoother, more efficient Java applications.
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar
The European Union Agency for Law Enforcement Cooperation (Europol) has suffered an alleged data breach after a notorious threat actor claimed to have exfiltrated data from its systems. Infamous data leaker IntelBroker posted on the even more infamous BreachForums hacking forum, saying that Europol suffered a data breach this month.
The alleged breach affected Europol agencies CCSE, EC3, Europol Platform for Experts, Law Enforcement Forum, and SIRIUS. Infiltration of these entities can disrupt ongoing investigations and compromise sensitive intelligence shared among international law enforcement agencies.
However, this is neither the first nor the last activity of IntekBroker. We have compiled for you what happened in the last few days. To track such hacker activities on dark web sources like hacker forums, private Telegram channels, and other hidden platforms where cyber threats often originate, you can check SOCRadar’s Dark Web News.
Stay Informed on Threat Actors’ Activity on the Dark Web with SOCRadar!
Enterprise Resource Planning System includes various modules that reduce any business's workload. Additionally, it organizes the workflows, which drives towards enhancing productivity. Here are a detailed explanation of the ERP modules. Going through the points will help you understand how the software is changing the work dynamics.
To know more details here: https://blogs.nyggs.com/nyggs/enterprise-resource-planning-erp-system-modules/
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamtakuyayamamoto1800
In this slide, we show the simulation example and the way to compile this solver.
In this solver, the Helmholtz equation can be solved by helmholtzFoam. Also, the Helmholtz equation with uniformly dispersed bubbles can be simulated by helmholtzBubbleFoam.
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxrickgrimesss22
Discover the essential features to incorporate in your Winzo clone app to boost business growth, enhance user engagement, and drive revenue. Learn how to create a compelling gaming experience that stands out in the competitive market.
5. @oldJavaGuy@ZalandoTech
THE SOLID Principles
• Single Responsibility Principle
• Open / Closed Principle
• Liskov Substitution Principle
• Interface Segregation Principle
• Dependency Inversions Principle
• Michael Feathers, Uncle Bob Martin, ~2003
6. @oldJavaGuy@ZalandoTech
Single Responsibility Principle
• Mapping production to test:
• 3 levels of production code (class, method, input)
• JUnit: 2 levels of test (class, method)
• Only one type of change should break any given test
A class should have only a single responsibility (i.e. only one potential
change in the software's specification should be able to affect the
specification of the class)
7. @oldJavaGuy@ZalandoTech
class StringUtils{ // dimension 1
// dimension 2
static String leftPad(String s, char c, int n){
if(s==null) return s; // dimension 3 a
if(n <= s.length()) return s; // dimension 3 b
StringBuilder sb = new StringBuilder(n);
for(int i = s.length(); i < n; i++){
sb.append(c);
}
// dimension 3 c
return sb.append(s).toString();
}
8. @oldJavaGuy@ZalandoTech
public class BadStringUtilsTest {
/* violates single responsibility
principle */
@Test public void badLeftPadTest() {
assertNull(leftPad(null, ' ', 10));
assertEquals("foo", leftPad("foo", ' ', 3));
assertEquals("foo", leftPad("foo", ' ', 4));
}
}
9. @oldJavaGuy@ZalandoTech
Open / Closed Principle
• Closed for modification applies to tests also
• Antipattern: Subclasses for Tests
• Antipattern: package protected access
• Better: Clean abstractions, mock objects
“Software entities should be open for extension, but
closed for modification”
10. @oldJavaGuy@ZalandoTech
class TightlyCoupledClass{
private final MyService ms = new MyServiceImpl();
public String foo(){ return ms.bar(); }
}
class TightlyCoupledClassTest{
@Test public void fooTest(){
TightlyCoupledClass t = new TCC(){
@Override public String foo(){
return "baz";
} };
assertEquals("baz", t.foo());
}
}
11. @oldJavaGuy@ZalandoTech
final class NotSoTightlyCoupledClass{
public NSTCC(MyService ms){this.ms = ms;}
private final MyService ms;
public String foo(){ return ms.bar(); }
}
class NotSoTightlyCoupledClassTest{
@Test public void fooTest(){
MyService ms = Mockito.mock(MyService.class);
NotSoTightlyCoupledClass n = new NSTCC(ms);
when(ms.bar()).thenReturn("baz");
assertEquals("baz", n.foo());
}
}
12. @oldJavaGuy@ZalandoTech
Liskov Substitution Principle
• When designing class hierarchies, design
corresponding test class hierarchies
• If the classes have a common contract, the same is
true for the test classes
“Objects in a program should be replaceable with instances of
their subtypes without altering the correctness of that program.”
13. @oldJavaGuy@ZalandoTech
abstract class AbstractCollectionTest{
protected abstract <T> Collection<T> create();
@Test public void equalsTest(){
assertEquals(create(), create());
}
// etc.
}
class ArrayListTest extends AbstractCollectionTest{
protected <T> Collection<T> create(){
return new ArrayList<>();
}}
class HashSetTest extends AbstractCollectionTest{
protected <T> Collection<T> create(){
return new HashSet<>();
}}}
15. @oldJavaGuy@ZalandoTech
class Multi implements Fooable, Barable {
@Override public String foo() { return "foo"; }
@Override public String bar() { return "bar"; }
}
class FooableMultiTest extends AbstractFooableTest {
@Override protected Fooable create() {
return new Multi();
}
}
class BarableMultiTest extends AbstractBarableTest {
@Override protected Barable create(){
return new Multi();
}
}
16. @oldJavaGuy@ZalandoTech
Dependency Inversion Principle
• Test public methods, not implementation details
• Test on the same level of abstraction as the
implementation
• Don’t change or test internal state
“Depend upon Abstractions. Do not depend upon
concretions.”
22. @oldJavaGuy@ZalandoTech
Hamcrest
• “Matchers that can be combined to create flexible
expressions of intent”
• Make tests (and failure output) readable
• Work on the correct abstraction level
• Built-in matchers, extendable with custom
matchers
25. @oldJavaGuy@ZalandoTech
// Error messages for Hamcrest Matchers:
private List<String> list;
Expected: a collection with size <1>
but: was null
list = Arrays.asList();
Expected: a collection with size <1>
but: collection size was <0>
list = Arrays.asList(" ");
Expected: a collection containing a non-empty
String but: was " "
26. @oldJavaGuy@ZalandoTech
Dependency Inversion
Principle revisited
• Abstraction in its main sense is a conceptual
process by which general rules and concepts are
derived from the usage and classification of
specific examples, literal ("real" or "concrete")
signifiers, first principles, or other methods.
Source: en.wikipedia.org/wiki/Abstraction
• The hard part is finding the right level of abstraction
27. @oldJavaGuy@ZalandoTech
Abstraction level: too low
• “Stringly typed”:
• Method parameters that
take strings when other
more appropriate types
should be used.
• Message passing without
using typed messages etc.
• Tests will most likely have to
parse custom Strings, tightly
coupling them to domain
knowledge
blog.codinghorror.com/new-programming-jargon/
28. @oldJavaGuy@ZalandoTech
Abstraction level: too high
• “Baklava Code”:
• While thin layers are fine for a
pastry, thin software layers
don’t add much value,
especially when you have
many such layers piled on
each other. Each layer has to
be pushed onto your mental
stack as you dive into the
code.
• Tests will most likely have to
either set up or mock multiple
layers, introducing tight coupling
blog.codinghorror.com/new-programming-jargon/
29. @oldJavaGuy@ZalandoTech
Example: JSON
• JSON (JavaScript Object Notation) is becoming the
lingua franca for Web-based (Restful?) APIs
• Almost every application deals with JSON in one
form or another
• How can we test JSON output for correctness?
30. @oldJavaGuy@ZalandoTech
public class ManualJsonTest {
private String json = "{ "id": 123, "name": "John Smith"}";
@Test
public void exactMatch() {
// missing a space breaks the assertion, although the semantics
// are still correct
assertEquals(json, "{"id": 123, "name": "John Smith"}");
}
}
Bad: Manual JSON assertions
False negatives through irrelevant things like
whitespace or property ordering
31. @oldJavaGuy@ZalandoTech
public class RegexJsonTest {
private String json = "{ "id": 123, "name": "John Smith"}";
@Test
public void regexMatch() {
// too technical, we have to effectively implement a JSON parser
// which violates the single responsibility principle
// also, re-ordering of properties is semantically correct
// but breaks the test
assertTrue(json.matches(
"{s*"id"s*:s*123s*,s*"name"s*:s*"John Smith"}"));
}
}
Bad: Regex JSON assertions
False negatives through property reordering or
grammar edge cases
32. @oldJavaGuy@ZalandoTech
public class JacksonJsonTest {
private String json = "{ "id": 123, "name": "John Smith"}";
@Test
public void jacksonMatch() throws IOException {
// better: we no longer have to implement our own parsing
JsonNode jsonNode = new ObjectMapper().readTree(json);
assertTrue(jsonNode.isObject());
// but this is still more complicated than necessary:
assertEquals(jsonNode.get("id").asInt(),123);
assertEquals(jsonNode.get("name").asText(),"John Smith");
}
}
Better: Using Jackson
Still: much boilerplate
Non-descriptive error messages
34. @oldJavaGuy@ZalandoTech
public class JaywayJsonTest {
String json = "{ "id": 123, "name": "John Smith"}";
@Test
public void jsonPathMatch() throws IOException {
JsonAssert.with(json)
.assertEquals("id", 123)
.assertEquals("name", "John Smith");
}
}
Perfect: Using JsonAssert
No boilerplate, automatic type conversion,
descriptive error messages
35. @oldJavaGuy@ZalandoTech
Matchers (summary)
• Look for existing matcher libraries
• Write your own matchers in a re-usable way
• start with a local factory method
• if you need it in another class, move it to a dedicated helper
class (e.g. XyzMatchers)
• if you need it in multiple projects, make your own matcher library
36. @oldJavaGuy@ZalandoTech
Mocking
mock: verb (gerund or present participle: mocking)
1. tease or laugh at in a scornful or contemptuous manner
2. make (something) seem laughably unreal or impossible
3. make a replica or imitation of something.
pragprog.com/magazines/2010-05/the-virtues-of-mockery
37. @oldJavaGuy@ZalandoTech
No, really
• A mock object is a testing tool that acts as a stand-in for a
“real” object during testing in much the same way as an Elvis
impersonator stands in for the real King. The impersonator is
cheaper, easier to access, and most likely lighter weight.
pragprog.com/magazines/2010-05/the-virtues-of-mockery
• Mocking in Java can take take numerous forms:
• overriding methods of the original class
• providing an alternative interface implementation
• creating a proxy (interface based or cglib etc.)
38. @oldJavaGuy@ZalandoTech
Recalling SOLID
• overriding methods of the original class
• violates Open / Closed principle
• providing an alternative interface implementation
• violates Interface segregation principle
• creating a proxy (interface based or cglib etc.)
• violates Dependency Inversion Principle
40. @oldJavaGuy@ZalandoTech
public interface UserService {
Optional<Session> login(
String user, String pass);
}
interface Session{ /* stuff in here */ }
public class LoginService {
private final UserService us;
public boolean login(String user, String pass){
return us.login(user, pass).isPresent();
}
}
41. @oldJavaGuy@ZalandoTech
public class LoginServiceTestWithoutMockito {
@Test
public void loginSuccess() {
LoginService ls = new LoginService(
(user, password) -> Optional.of(new Session() {}));
assertTrue(ls.login("ali baba", "open sesame"));
}
@Test
public void loginFailure() {
LoginService ls = new LoginService((user, password) -> Optional.empty());
assertFalse(ls.login("ali baba", "open sesame"));
}
}
Mocking without Mockito
• if interface evolves, all tests break
• code duplication, no common setup
42. @oldJavaGuy@ZalandoTech
public class LoginServiceTestWithMockito {
UserService userService; LoginService ls;
@Before public void setUp(){
userService= mock(UserService.class);
ls = new LoginService(userService);
}
@Test public void loginSuccess() {
when(userService.login(anyString(), anyString()))
.thenReturn(Optional.of(mock(Session.class)));
assertTrue(ls.login("ali baba", "open sesame"));
verify(ls,times(1)).login("ali baba", "open sesame"));
}
}
Mocking with Mockito
• Common setup
• No tight coupling to UserService and Session
• Verify mock interaction (reduce false positives)
43. @oldJavaGuy@ZalandoTech
Advanced Mockito
• All methods in a mock return default values (null for
references, 0 or false for primitives)
• Use Mockito.spy(object) to wrap an existing object
inside a mock
• Use .thenAnswer() to interact with method
parameters rather than return static values
• Use deep stubs to return chained mocks (huge
code smell, but useful for legacy code)
44. @oldJavaGuy@ZalandoTech
Mocking Web APIs
• Scenario: Testing API clients
• Blackbox:
• Faking the API calls by a 3rd party Mock Server
• MockServer, WireMock
• Whitebox:
• Using the API’s own code to create the Mock
• Example: Spring MockMvc
• No actual network call, mock requests / responses
45. @oldJavaGuy@ZalandoTech
new MockServerClient("127.0.0.1", 1080)
.when(
request()
.withMethod("POST").withPath("/login")
.withQueryStringParameters(new Parameter("returnUrl", "/account"))
.withBody(exact("{username: 'foo', password: 'bar'}")),
exactly(1)
)
.respond(
response()
.withStatusCode(401)
.withHeaders(
new Header("Content-Type", "application/json; charset=utf-8"),
new Header("Cache-Control", "public, max-age=86400")
)
.withBody("{ message: 'incorrect username and password combination' }")
);
Example: MockServer
• set up behavior to mimic real API
• start up server via @Before method or @Rule
46. @oldJavaGuy@ZalandoTech
Spring Mvc Controller
@RestController @RequestMapping("/contacts")
public class ContactController {
private final ContactRepository contactRepository;
public ContactController(ContactRepository contactRepository) {
this.contactRepository = contactRepository;
}
@RequestMapping(method = GET, value = "/{contactId}")
public Contact getContact(@PathVariable int contactId) {
return contactRepository.findOne(contactId);
}
}
47. @oldJavaGuy@ZalandoTech
public class ContactControllerTest {
ContactRepository contactRepository; MockMvc mockMvc;
@Before public void setup() {
contactRepository = mock(ContactRepository.class);
ContactController controller = new ContactController(contactRepository);
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@Test public void getContactById() throws Exception {
final Contact contact = new Contact();
contact.setFirstName("Jim");
when(contactRepository.findOne(anyInt())).thenReturn(contact);
mockMvc.perform(get("/contacts/123").accept(APPLICATION_JSON)) //
.andExpect(status().isOk()) //
.andExpect(content().contentType(APPLICATION_JSON)) //
.andExpect(jsonPath("$.firstName").value("Jim"));
}
}
MockMvc
• Request / response cycle is virtual
• Integrates nicely with Mockito and JsonPath
49. @oldJavaGuy@ZalandoTech
Basic Lifecycle
• @Before / @After
• instance, before / after every test
• setting up / cleaning up test data
• instantiating classes and mocks
• @BeforeClass / @AfterClass
• static, before / after entire test class
• bootstrapping databases and web servers
• creating and deleting temporary folders
50. @oldJavaGuy@ZalandoTech
Okay, but
• What if I need the same kind of setup in many
tests?
• Move the setup to an abstract test class
• If setup needs test-specific parameters, get them
from abstract methods
51. @oldJavaGuy@ZalandoTech
Inheritance vs aggregation
• This works fine for test hierarchies with a clear relation
(“AbstractUserServiceTest” -> “UserServiceLoginTest”)
• LSP says: common hierarchies for production and tests
• Which means: we probably shouldn’t have an
AbstractDBIntegrationTest, since we probably don’t
have an AbstractDatabaseService
• Okay, so how can we embrace DRY without
inheritance?
52. @oldJavaGuy@ZalandoTech
Custom JUnit Runners
• @RunWith(someclass) replaces JUnit’s standard Runner
• Full control over entire lifecycle
http://www.rockcellarmagazine.com/2012/10/01/the-man-behind-darth-vader/
53. @oldJavaGuy@ZalandoTech
Example Runners
• SpringJunit4Runner
• Ties JUnit lifecycle to Spring lifecycle
• Dependency injection, transaction handling
• MockitoRunner
• Mocks all fields annotated with @Mock
• Parameterized
• Runs tests with parameters
54. @oldJavaGuy@ZalandoTech
@RunWith(Parameterized.class)
public class FibonacciTest {
@Parameters public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{ 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 },
{ 4, 3 }, { 5, 5 }, { 6, 8 }
});
}
@Parameter(0) public int fInput;
@Parameter(1) public int fExpected;
@Test public void test() {
assertEquals(fExpected, Fibonacci.compute(fInput));
}
}
Parameterized Example
• Generates one test per method, per values array
• Values are common for all test methods
55. @oldJavaGuy@ZalandoTech
• You can’t mix runners (e.g. Spring + Mockito)
• Runner interface is very technical
• You have to do everything
http://www.quickmeme.com/meme/35n2io
Runner Drawbacks
57. @oldJavaGuy@ZalandoTech
public static class HasTempFolder {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Test
public void testUsingTempFolder() throws IOException {
File createdFile = folder.newFile("myfile.txt");
File createdFolder = folder.newFolder("subfolder");
// ...
}
}
Example test rule
• Rules can interact with test lifecycle
• @Rule is per test, @ClassRule is per test class
58. @oldJavaGuy@ZalandoTech
public class NTimes implements TestRule {
private final int times; private final Logger logger;
public NTimes(final int times, final Logger logger) {
this.times = times; this.logger = logger; }
@Override public Statement apply(Statement base, Description desc) {
return new Statement() {
@Override public void evaluate() throws Throwable {
StopWatch stopWatch = new StopWatch();
for (int i = 0; i < times; i++) { base.evaluate();}
logger.info("Executed {} times in {} ms", times,
stopWatch.getLastTaskTimeMillis());
}};
}}
Implementing our own rule
• runs every test n times, logs total duration
59. @oldJavaGuy@ZalandoTech
Lifecycle recap
• Use @Before / @After for specific local setup
• Use @Rule / @ClassRule if you want to reuse setup
logic, ideally move your rules to libraries
• Use custom runners for parameterized testing or
Spring (but you can’t combine them)
• You probably shouldn’t write a custom runner
62. @oldJavaGuy@ZalandoTech
class ExampleSpec extends FlatSpec with Matchers {
"A Stack" should "pop values in last-in-first-out order" in {
val stack = new Stack[Int]
stack.push(1)
stack.push(2)
stack.pop() should be (2)
stack.pop() should be (1)
}
it should "throw NoSuchElementException if an empty stack is popped" in {
val emptyStack = new Stack[Int]
a [NoSuchElementException] should be thrownBy {
emptyStack.pop()
}
}
}
Example from ScalaTest
63. @oldJavaGuy@ZalandoTech
Differences
• Java:
• tests are defined through annotated methods, instantiated through
reflection
• 2 levels of nesting (class, method)
• Scala:
• tests are defined programmatically, using a DSL
• no isolation: runtime error in one test destroys everything
• arbitrary levels of nesting
• many different ways to write tests
66. @oldJavaGuy@ZalandoTech
Matchers
• Extend your test class with the Matchers trait
• Matchers enable “readable” assertions with the
“should” keyword, e.g.
result should have length 3
file should have ('name ("temp.txt"))
• You can create custom matchers and combine
them using a DSL
67. @oldJavaGuy@ZalandoTech
trait CustomMatchers {
class ExtensionMatcher(expected: String)
extends Matcher[java.io.File] {
def apply(left: java.io.File) = {
val name = left.getName
MatchResult(
name.endsWith(expected),
s"""File $name did not end with extension "$expected"""",
s"""File $name ended with extension "$expected""""
)
}
}
def hasExtension(extension: String) = new ExtensionMatcher(extension)
}
Custom matcher
68. @oldJavaGuy@ZalandoTech
Property-based testing with
ScalaCheck
• ScalaCheck is a tool for testing Scala and Java
programs, based on property specifications and
automatic test data generation.
• Define a property that specifies the behaviour of a
method or some unit of code, and ScalaCheck
checks that the property holds.
• All test data are generated automatically in a
random fashion, so you don't have to worry about
any missed cases.
69. @oldJavaGuy@ZalandoTech
class Fraction(n: Int, d: Int) {
require(d != 0)
require(d != Integer.MIN_VALUE)
require(n != Integer.MIN_VALUE)
val numer = if (d < 0) -1 * n else n
val denom = d.abs
override def toString = numer + " / " + denom
}
Class to test
70. @oldJavaGuy@ZalandoTech
class PropertySpec extends FlatSpec with PropertyChecks
with Matchers {
forAll { (n: Int, d: Int) =>
whenever(d != 0 && d != Integer.MIN_VALUE
&& n != Integer.MIN_VALUE) {
val f = new Fraction(n, d)
if (n < 0 && d < 0 || n > 0 && d > 0)
f.numer should be > 0
else if (n != 0) f.numer should be < 0
else f.numer should be === 0
f.denom should be > 0
}
}
Property Testing (Part1)
72. @oldJavaGuy@ZalandoTech
JUnit ScalaTest
Use Hamcrest Matchers Mix in Matchers Trait
@Before, @After Do it in code
@Rule Mix in a trait
Parameterized runner Property Testing with ScalaCheck
Solving similar problems in
JUnit and ScalaTest
73. @oldJavaGuy@ZalandoTech
What now?
• Java and Scala can be combined
• You can write tests for your Java code in Scala
• No runtime dependencies to Scala
• Scala can be integrated easily into all major build
systems and IDEs
74. @oldJavaGuy@ZalandoTech
OK but what if I really don’t
like Scala?
• JUnit 4 is also kinda cool when you use Hamcrest,
Mockito and Rules
• JUnit 5 will come soon, supporting lots of new cool
features:
• New test callback mechanism
• Dynamic test generation (limited)
• Lambda support
78. @oldJavaGuy@ZalandoTech
The madness
• Stripes relies on static initialization in a Servlet Filter
• Controllers, Localization and many other
components depend on this state
• Spring integration is worse:
ContextLoader
.getCurrentWebApplicationContext()
.getBean(MyBean.class)
79. @oldJavaGuy@ZalandoTech
Divide and conquer
• Create solutions for Stripes and Spring, separately
• Make sure you tear up everything you set up
• Keep low-tech hacks in one place
• Provide high level facades for your tests
80. @oldJavaGuy@ZalandoTech
static StripesFilter stripesFilter;
static MockServletContext ctx;
public static void initStripes() throws Exception {
if (!stripesIsAlreadyActive()) {
stripesFilter = new StripesFilter();
final MockFilterConfig config = new MockFilterConfig();
config.addInitParameter("ActionResolver.Packages", "de.zalando.shop.frontend.stripes.action");
ctx = new MockServletContext(); config.setServletContext(ctx);
stripesFilter.init(config);
}
}
public static void shutdownStripes() throws Exception {
if (stripesFilter != null) {
stripesFilter.destroy(); stripesFilter = null; ctx = null; }
}
private static boolean stripesIsAlreadyActive() {
final Logger stripesLogger = Logger.getLogger(StripesFilter.class);
final Level oldLevel = stripesLogger.getLevel();
stripesLogger.setLevel(Level.FATAL);
try { new LocalizableMessage("link.catalog") .getMessage(Locale.GERMAN);
return true; } catch (final Exception e) { return false; }
finally { stripesLogger.setLevel(oldLevel); }
}
StripesTestUtils (extract)
84. @oldJavaGuy@ZalandoTech
• You develop a grammar, ANTLR will generate the
parser class for it
• Example grammar:
grammar Expr;
prog:(expr NEWLINE)* ;
expr:expr ('*'|'/') expr
| expr ('+'|'-') expr
| INT
| '(' expr ')';
NEWLINE : [rn]+ ;
INT : [0-9]+ ;
85. @oldJavaGuy@ZalandoTech
How to unit test a grammar?
• Grammars consist of rules
• Let’s try to test rules separately
• Each rule is a dedicated method in the parser, and it’s
protected, so we have to hack it
• Let’s use convention over configuration to generate
test from sample files
• We’ll use the file naming convention <rule>.txt and
create test dynamically with ScalaTest
86. @oldJavaGuy@ZalandoTech
describe("Valid examples for") {
baseDir.listFiles().foreach({
(f) => {
val ruleName: String = f.getName.replace(".txt", "")
describe(ruleName) {
try { val method: Method = parserType.getDeclaredMethod(ruleName)
describe("should be successfully parsed") {
val source: String = new String(Files.readAllBytes(f.toPath), UTF_8)
val index = new AtomicInteger();
source.split("---+").map(stripComments).foreach((src) => {
val ct: Int = index.getAndIncrement()
it("item[" + ct + "]") {
val parser: P = parserFor(src, ruleName)
try { method.invoke(parser) } catch {
case e: InvocationTargetException
=> fail(s"$ruleName[${ct}]", e.getCause)
} } }) }
} catch {
case e: NoSuchMethodException => {
err.println(s"Bad rule name: $ruleName")
} } } } }) }
Generating tests dynamically
88. @oldJavaGuy@ZalandoTech
Law of Demeter
• the Law of Demeter for functions
requires that a method m of an
object O may only invoke the
methods of the following kinds of
objects:
• O itself
• m's parameters
• Any objects created / instantiated
within m
• O's direct component objects
• A global variable, accessible by
O, in the scope of m
https://commons.wikimedia.org/wiki/File:Demeter_Altemps_Inv8596.jpg