Frontend Web Development with Angular CC BY-NC-ND Carrot & Company GmbH
Agenda ● Questions Some infos ● ● Testing of Frontend Applications ● Todos CC BY-NC-ND Carrot & Company GmbH
Questions? CC BY-NC-ND Carrot & Company GmbH
Some Infos ● Use constants and put them in a separate file if they might be used elsewhere. ● Consistent coding style (see Angular Style Guide for naming conventions) ● Use Angular modules and structure your code CC BY-NC-ND Carrot & Company GmbH
Testing of Frontend Applications CC BY-NC-ND Carrot & Company GmbH
Today's Topics ● Motivation & Reasons Types of Tests ● ● Frameworks ● Jest Matcher ○ ○ Mocks & Spies Snapshot testing ○ ○ Test asynchronous code Coverage Reports ○ ● Angular Testing Utilities ○ Query DOM elements & trigger events Shallow Component Tests ○ CC BY-NC-ND Carrot & Company GmbH
Today's Topics ● Cypress Querying Elements ○ ○ Interacting With Elements Assertions ○ ○ Core Concepts Best Practices ○ ● Configuration for Jest and Cypress ● Live Coding Commands for starting the tests ○ ○ Utility Functions Write Unit & Integration Tests with Jest ○ ○ Write E2E Tests with Cypress CC BY-NC-ND Carrot & Company GmbH
Motivation ● You are implementing a new feature, feature 1. When it is implemented, it works, so you do not need any tests, right?! ● ● You deploy your application to production. ● You want to proceed, implement more features and deploy them. ● Suddenly feature 1 breaks, because you refactored a service that is used by feature 1. ● At this point you regret that you (or even better, your teammate) did not write any tests. CC BY-NC-ND Carrot & Company GmbH
Reasons to write tests ● It saves time Code refactoring is a “no go” because you can not see what parts of your application will fail ○ ○ Had no time for writing tests? Your crappy implementation stays. Developing becomes more fun as you are not being blocked by hard to find bugs. ○ CC BY-NC-ND Carrot & Company GmbH
Reasons to write tests ● Self-updating documentation Some people like to read the comments ○ ○ Some read the implementation itself But some read the tests ○ ● It is fun ○ People that write good tests, are also the best programmers Your test is also a program ○ ○ If you like programming, you should like writing tests CC BY-NC-ND Carrot & Company GmbH
Reasons to write tests ● Preventing regression bug When you find a bug ○ ■ First write a (failing) test that reproduces the bug Then fix the bug ■ ■ This will never happen again ● Improve the implementation via new insights Write tests and have trouble with it → maybe an indication that your implementation can be ○ improved Your tests let you think about input and output, corner cases and dependencies ○ CC BY-NC-ND Carrot & Company GmbH
Reasons to write tests ● 100% coverage feels good and makes you happy :) CC BY-NC-ND Carrot & Company GmbH
Type of Tests ● Unit Tests Integration Tests ● ● End-2-End Tests (E2E) There are more than 100 different tests, but these three are the major types of frontend testing. More types of tests: https://www.softwaretestinghelp.com/types-of-software-testing/ CC BY-NC-ND Carrot & Company GmbH
Unit Tests ● Test units in encapsulation Should have a very narrow and well defined scope ● ● Perfect for code that has no I/O or UI dependencies ● Keep modules independent of one another ● If there is a dependency, either mock the dependency or do integration tests Reasons to use functional programming and pure functions as much as ● possible ○ The purer your application is, the easier you can test it ○ https://blog.mgechev.com/2017/11/12/faster-angular-applications-pure-pipes-memoization-pure-functions-part-2/ CC BY-NC-ND Carrot & Company GmbH
Integration Tests ● Tests that check the integration of two or more units components, modules, classes, I/O, etc. ○ ● Just check that the glue binding of some units works ● If the real I/O is difficult, slow, or flaky then in the integration tests test using a fake/mock ○ Using a real DOM (using the browser) make the tests slow and flaky → virtual DOM (VDOM) ■ CC BY-NC-ND Carrot & Company GmbH
End-2-End Tests ● Test the whole application together, and test it as a user would Check that the glue binding of all units works ● ● Tests if all units are working together ● E2E tests tend to be flaky Flaky tests are tests that usually pass, but sometimes fail ○ ○ Reasons: Different Timing ■ ■ I/O (real browser, network, etc) ● Testing the main flows of your application not every detail CC BY-NC-ND Carrot & Company GmbH
Testing Pyramid Efficiency Flakiness E2E Tests Integration Tests Unit Tests Number of Tests CC BY-NC-ND Carrot & Company GmbH
Frameworks ● Karma Test runner ○ ○ Unit & integration tests https://karma-runner.github.io/latest/index.html ○ ● Jasmine Framework to write tests (matcher, etc.) ○ ○ Unit, integration & E2E tests https://jasmine.github.io/ ○ ● Protractor ○ Framework to run and write E2E tests for angular applications https://www.protractortest.org ○ Are part and pre-configured within a new Angular project ( ng new <project-name> ) CC BY-NC-ND Carrot & Company GmbH
Frameworks ● Jest Framework to write and run tests ○ ○ Unit & Integration tests https://jestjs.io/ ○ ● Cypress Framework to write and run E2E tests for any web application ○ ○ https://www.cypress.io/ Our testing stack (already configured in your applications) CC BY-NC-ND Carrot & Company GmbH
Why we do not use the default testing stack? ● Jest Pro: ○ ■ It’s fast Uses jsdom (VDOM) (not slow, flaky browser) ■ ■ Executes tests in parallel Sits on top of Jasmine, so the API is nearly identical ■ ■ Provides code coverage out of the box Provides a smart, immersive watch mode ■ ● Runs only tests affected by git file changes Also runs failed tests first ● ● Is able to stop on first error so the feedback loop is ~10x faster than with Karma (depending on test suite size) ■ Provides snapshot testing Con: ○ https://blog.nrwl.io/nrwl-nx-6-3-faster-testi ■ Uses jsdom (VDOM) (no real browser) ng-with-jest-20a8ddb5064 CC BY-NC-ND Carrot & Company GmbH
Why we do not use the default testing stack? ● Cypress Pros: ○ ■ No dependencies Auto-reload ■ ■ UI for debugging Automatic waits ■ ● No manual sleeps or waits Waiting for element to appear in the DOM ● ■ Clear and easy syntax Cons: ○ ■ Small Community Lack of Features ■ ■ Variety of browsers https://blog.nrwl.io/nrwl-nx-7-0-better-e2e-testing-wi th-cypress-1b88336bef5e CC BY-NC-ND Carrot & Company GmbH
Jest Test Suite Setup & Teardown Test Matcher Matcher: https://jestjs.io/docs/en/using-matchers, https://jestjs.io/docs/en/expect Setup & Teardown: https://jestjs.io/docs/en/setup-teardown CC BY-NC-ND Carrot & Company GmbH
Jest ● Mocks Used in unit testing ○ ○ Object under test may have dependencies on other objects. To isolate the behavior of the dependencies you can replace these dependencies by mocks. These mocks will simulate the behavior of the real objects. Mocking is creating objects that simulate the behavior of real objects ○ ○ const a = new A(new MockB(), new MockC()) ○ Mock functions in Jest with jest.fn(implementation) : https://jestjs.io/docs/en/mock-functions CC BY-NC-ND Carrot & Company GmbH
Jest ● Spies Keep track of the usage of a method of a class ○ ○ jest.spyOn(object, methodName) Creates a mock function similar to jest.fn but also tracks calls ○ ○ By default, jest.spyOn also calls the spied method https://jestjs.io/docs/en/jest-object#jestspyonobject-methodname CC BY-NC-ND Carrot & Company GmbH
Important: Do not make snapshots of large component or Jest object because the snapshots could be hard to maintain! ● Snapshot testing Very useful tool whenever you want to make sure your UI or an object does not change ○ unexpectedly ○ expect(object).toMatchSnapshot(); Angular Component: my-test-component/ __snapshots__/my-test-component.component.spec.ts.snap https://jestjs.io/docs/en/snapshot-testing CC BY-NC-ND Carrot & Company GmbH
Jest ● Testing Asynchronous Code When you have asynchronous code, Jest needs to know when the code it is testing has ○ completed, before it can move on to another test. Use ○ ■ Callback Marble tests ■ CC BY-NC-ND Carrot & Company GmbH
Jest Callback: Jest tests complete once they reach the end of their execution. That means this test will not work as intended! https://jestjs.io/docs/en/asynchronous CC BY-NC-ND Carrot & Company GmbH
Marble Test: Jest rxjs-marbles: https://github.com/cartant/rxjs-marbles https://github.com/cartant/rxjs-marbles/tree/master/examples/jest hot vs cold observable: https://medium.com/@luukgruijs/understanding-hot-vs-cold-observables-62d04cf92e03 CC BY-NC-ND Carrot & Company GmbH
Recommend
More recommend