WDX-180
Web Development X
Week 32 | Testing

Week 32 - Day 1 | Testing
Schedule
- Watch the lectures
- Study the suggested material
- Practice on the topics and share your questions
Study Plan
Your instructor will share the video lectures with you. Here are the topics covered:
- Testing & Testing React Apps
You can find the lecture code here and the diagram here.
Lecture Notes & Questions:
References & Resources:
- Colored console output?
- Check this SO thread: https://stackoverflow.com/questions/9781218/how-to-change-node-jss-console-font-color
- Testing pyramid (Google for a couple of images and take a good look at a few of them)
- Unit Tests:
- Some things to consider:
- Always implement as many tests as you can after developing a specific function or feature (before moving on to the next part of your code).
- ALWAYS make sure to break your tests in order to test them (tests are code that should be tested)
- Try to have a high test coverage, meaning all parts of the code should be tested.
- Your functions must do one thing and one thing only
- 1) They adhere to the Single Responsibility Principle
- You can easily test if your functions follow this principle by picking a function and asking yourself to describe what this function is doing. If the description (your response) contains the word “and”, you should probably break this down into multiple functions. Example: “this function fetches the user data, calculates and displays the average rating.” You probably want to break this down into 3 functions: fetchUserData(userId):userData => calculateAvgRating(userData):avgRating => renderData(avgRating):void => Expect to see the average rating in the screen
- There might be the case where you want to combine these units into a function: displayAvgUserData()
- 2) Your functions should be pure, meaning they should have no side-effects (affecting parts of the code that is outside the function body).
- A pure function is a function that accepts an input, treats this input (argument(s) as a read-only (immutable) value, and produces and returns some kind of output value. A pure function should always give the same output given the same input. 40,2 in => 42 out (ALWAYS)
- A function that works with a global variable, or changes a variable that belongs to the outer scope is an impure function.
- Always implement as many tests as you can after developing a specific function or feature (before moving on to the next part of your code).
- Some things to consider:
- ts-node
- A real-life example from GitHub where application is complemented with thorough testing:
Exercises
- Challenge: optimize and improve the UTILS.test.js so that there is an Error or Success message at the end. If all the tests pass, you should see the number of tests that succeeded along with a green output and some emoji. If some of the tests fail, you should see some relevant information displayed in red with a X emoji.
- Example:
✅All tests (5/5) completed successfully. - Example: ❌Tests failed. Passed 3/5.
- Example:
- Challenge: improve the test coverage of the UTILS.js by handling as many edge cases as you can (null, undefined, wrong types, large numbers, etc.).
- Challenge: How to use tsc (or npx tsc) to target specific files? (and avoid tsc scanning node_modules, etc.)?
- Challenge: How to run ts-node and have it execute .ts files without errors!
- Study:
IMPORTANT: Make sure to complete all the tasks found in the daily Progress Sheet and update the sheet accordingly. Once you’ve updated the sheet, don’t forget to commit and push. The progress draft sheet for this day is: /user/week32/progress/progress.draft.w32.d01.csv
You should NEVER update the draft sheets directly, but rather work on a copy of them according to the instructions found here.
Week 32 - Day 2 | Testing
Schedule
- Watch the lectures
- Study the suggested material
- Practice on the topics and share your questions
Study Plan
Your instructor will share the video lectures with you. Here are the topics covered:
- TypeScript & Testing FTW
You can find the lecture code here
Lecture Notes & Questions:
- TypeScript + React:
- How to define types for hooks:
const r = useState<POSSIBLE_TYPES_HERE>(INITIAL_VALUE)const r = useState<string|null|number>(null)const r = useRef<HTMLFormElement|null>(null)
- How to define types for hooks:
(method) ParentNode.querySelector<Element>(selectors: string): Element | null (+4 overloads)- This is the TypeScript signature for the
documentQuerySelector() - ParentNode: this is the TS type for the Object that contains this method
documentcan be ofParentNodedocument.querySelector(“.an-element”).querySelector()
<Element>: ?Element|nullthe return type
- This is the TypeScript signature for the
- VSCode: Settings => search for auto-save =>
files.autoSaveWhenNoErrors - VSCode: Pretty TypeScript Errors
- Testing document/DOM-API in Vitest
- Initially when you use document.* in tests you’ll get “document is not defined” because vitest runs in Node.js environment where DOM is not a thing.
- One solution would be to:
- Install jsdom (or happy-dom):
npm install --save-dev jsdom - Put this comment in your tests:
- Install jsdom (or happy-dom):
/** * @vitest-environment jsdom */- Alternatives exist through the configuration files (vite.config.json, vitest.config.json or vitest.config.ts???, ts.config.json, etc.)
- Check the docs: https://vitest.dev/config/#environment
- Vitest: you can either skip certain tests or focus on individual tests by using the following methods on the it(), describe() and test() methods of vitest:
it.skip(...)it.only(...)describe.skip()ordescribe.only()test.skip()ortest.only()
- Be very careful with NaN checks, because NaN === NaN will ALWAYS BE false
- The safest way is through Number.isNaN( value )
- CAUTION: There is also a global isNaN(). AVOID IT!
- utils.ts:10 Uncaught Error means there’s an Error thrown somewhere and you are not explicitly handling it, e.g. try/catch, catch(), etc.
- For testing React Components we need to bring in React Testing Library
- https://testing-library.com/docs/react-testing-library/intro
- For TS:
npm install --save-dev @testing-library/react @types/react-dom @types/react
- For TS:
- Great intro to RTL: https://www.robinwieruch.de/vitest-react-testing-library/
- https://testing-library.com/docs/react-testing-library/intro
- When installing npm packages (and if they do not already include TypeScript types) you can use the @types repo:
npm i sharpnpm i -D @types/sharpnpm install reactnpm install --save-dev @types/react
Exercises
- Do you know the
<picture>elements?- Cropping or modifying images for different media (screen sizes) conditions
- Offering alternative image formats, for cases where certain formats are not supported.
- You can serve the highly compressed webp image type for browsers that support this format and provide an alternative fallback for older browsers that do no support webp
- Study open source projects (GitHub, GitLab, Bitbucket) and take a look at how they organize tests
- sharp (a Node.js module for working with images on the server)
- Testing Library (which includes React Testing Library): “The @testing-library family of packages helps you test UI components in a user-centric way.”
- Discover React Testing Library:
- The methods available for querying the DOM (grabbing HTML elements)
- The methods for testing whether these selected elements have a particular property, e.g. contain some text, etc.
- The methods for triggering actions, e.g. enter value in an input, click a button
IMPORTANT: Make sure to complete all the tasks found in the daily Progress Sheet and update the sheet accordingly. Once you’ve updated the sheet, don’t forget to commit and push. The progress draft sheet for this day is: /user/week32/progress/progress.draft.w32.d02.csv
You should NEVER update the draft sheets directly, but rather work on a copy of them according to the instructions found here.
Week 32 - Day 3 | Practice Day
Schedule

- Practice on the topics and share your questions
Study Plan
Today is practice day. Practice on the topics covered yesterday and share your thoughts, questions and insights.
Happy hacking!
Week 32 - Day 4 | Async Mysteries
Schedule
- Watch the lectures
- Study the suggested material
- Practice on the topics and share your questions
Study Plan
Your instructor will share the video lectures with you. Here are the topics covered:
- Asynchronous code and the HTMLImageElement
- Promises and more asynchronous mysteries
You can find the lecture code here and the diagrams here.
Lecture Notes & Questions:
References & Resources:
- Events are things that happen during the lifecycle of a web application and these are events triggered by the user or the system (either the browser or external actors, e.g. a server sending a message);
- JS Modules are deferred by default
- Async vs Defer - Network Optimisation for Web Apps
new Image()creates a newHTMLImageElementobject (go check MDN on that)- Progressive JPEG images
Exercises
- Challenge: make sure to start the game or display a Start Game button or run any code when ALL the images have been loaded. (game.js)
- Tricky part: how to deal with some errors that might happen. Example: make sure that some image URLs are correct (and therefore loaded) and some URLs are misspelled, instead of image.jpg, write image.jpgZZZ or iiii.jpg
- In cases like these, we tend to inform the user and act accordingly: retry loading the images that were not loaded, or run the code without using them.
- Tricky part: how to deal with some errors that might happen. Example: make sure that some image URLs are correct (and therefore loaded) and some URLs are misspelled, instead of image.jpg, write image.jpgZZZ or iiii.jpg
- CHALLENGE: How can you get access to all the loaded images (when they have loaded) in the callback function?
- CHALLENGE: Try displaying a percentage loader while the images are loading.
- When the first one has loaded, show: 33%
- When the 2nd, show: 66%
- When all of them show: 100%
- Or use a loading spinner so that the users know that something is loading.
IMPORTANT: Make sure to complete all the tasks found in the daily Progress Sheet and update the sheet accordingly. Once you’ve updated the sheet, don’t forget to commit and push. The progress draft sheet for this day is: /user/week32/progress/progress.draft.w32.d04.csv
You should NEVER update the draft sheets directly, but rather work on a copy of them according to the instructions found here.
Week 32 - Day 5 | End-to-End Testing & TDD
Schedule
- Watch the lectures
- Study the suggested material
- Practice on the topics and share your questions
Study Plan
Your instructor will share the video lectures with you. Here are the topics covered:
- End-to-End Testing and Test Driven Development (TDD)
You can find the lecture code here and the diagrams here.
Lecture Notes & Questions:
References & Resources:
- Testing:
- AAA: Arrange, Act, Assert Pattern
- RTL: getByTestId
- ALWAYS BREAK YOUR TESTS AND MAKE SURE THAT THEY FAIL
- GitHub: when you are viewing a repo, press the . to go into VSCode Dev mode
- Supabase tests: https://github.dev/supabase/supabase/tree/master/tests
- Screenshot regression testing
- https://www.cypress.io/ (Integration/Component/E2E)
- Nightwatch
- Playwright
- RTL also supports: Snapshot Testing
- Test-Driven-Development (TDD)
- FizzBuzz
Exercises
- Research and study the AAA
- PRACTICE:
- Study and practice based on this article: A really simple example of TDD in JavaScript
- Try to find and practice on the “99 bottles of beer” song test
- Sandi Metz has some great workshops
IMPORTANT: Make sure to complete all the tasks found in the daily Progress Sheet and update the sheet accordingly. Once you’ve updated the sheet, don’t forget to commit and push. The progress draft sheet for this day is: /user/week32/progress/progress.draft.w32.d05.csv
You should NEVER update the draft sheets directly, but rather work on a copy of them according to the instructions found here.
Weekly feedback: Hey, it’s really important for us to know how your experience with the course has been so far, so don’t forget to fill in and submit your mandatory feedback form before the day ends. Thanks you!