oslabs-beta / SvelteSlicer

MIT License
20 stars 5 forks source link

Hb register component testing #44

Closed heatherbarney closed 1 year ago

heatherbarney commented 1 year ago

This PR adds integration testing for the RegisterComponent event handling functionality, and builds out a testing environment that should be easily extended for further integration testing of future functionality.

Testing To test the functionality of this PR, run "npm run test" and verify that jest runs error free and that all fourteen tests are passing. Probably also a good idea to make sure that all functionality from the previous PR is still working. (When run with an actual app instance in the browser, it should still produce the same three console logs of representations, instances, and 'capture snapshot' for each DOM update. All scripts in package.json should still run properly as well.)

Why The previous iteration of automated testing for the backend had a handful of unit tests, but they were fairly trivial and not really getting at the thing we really want to be able to validate, which is the complete chain of events - capturing all the SvelteRegisterComponent events from a user app in the Router instance, transforming the event data about those components into usable representations in the SvelteEventParser instance, and storing relevant data for future use in the DataStore. We're currently manually inspecting this chain via console.logs in the browser, but this is time-consuming and error prone, so automation would be helpful. This PR should create the building blocks for greater speed and confidence in our backend system moving forward.

How To do this kind of testing, we need a test environment where a running "mock" user app instance will build a DOM object and fire events just like it would in the browser . We also need to be able to run an instance of our Router class in the same context as the mock app, and access that Router instance from the testing context to be able to inspect internals of our backend system.

TestAppContext The new "TestAppContext" file defines a class to create this environment. The constructor stores router and app instances so they can be shared with the test runner after the test setup occurs. The setup method takes a root-level Svelte component (referred to as the appInstance). It uses a package called happy-dom that creates a Node-runnable implementation of a web browser that can be run in the global context. Then it creates and stores a Router instance and an instance of the particular mock app that's been passed to it.

Test file In the file containing the actual tests, I created an instance of TestAppContext so that the setup method and router and app instances are available to Jest. There's an outer "describe.each" block that acts a bit like a forEach loop - it's given an array of testing data, and will run the same set of functionality for each array element. In this case, the array contains mock Svelte apps coupled with expectations about their components to Jest can use to match against.

Within the "describe.each" block, the setup method from TestAppContext is invoked, creating the running app and router instances, and then there are a set of assertions to test that RegisterComponent events are being handled as they should be - specifically that the correct number of component instances and component representations with the correct labels are being stored, and that the instance and representation values have the correct form/type.

Testing Data To give us some actual data to test against, I created a "mocks" folder containing several simple mock applications composed of some basic mock components that can be combined in different ways, and defined expectations in a file called "testData" about how our system should process each app. At this point the only functionality the devtool provides deals with the outer shell of the component instances themselves (ie. how many, what they're called...) so these are VERY simple components, but we'll be able to add new component functionality and more mock apps as needed to capture more devtool functionality moving forward.

Build Process for Testing I also needed to create a version of the backend build that would allow us to access the Router instance. Normally we are building the backend system into a script for injection into the browser with no need to retain a reference to anything, so the entrypoint at "main.js" contains an IIFE that automatically creates a Router instance on injection and doesn't store or return the instance.

For testing purposes, we need the main function in our backend entrypoint to provide an exported function that we can directly invoke, and we need that function to return the Router instance so we have access to its internals. So I created an alternate entrypoint called "testMain.js" to alter the initialization function in this way, along with another webpack config called "scriptTest" that uses this new entrypoint and that emits a module library rather than a script.

package.json was updated to reflect a new script for this new build process, and to add that build script as a step in the "test" script. Running "test" will now build the test version of the current backend source files, and then run Jest once that test backend is ready. package.json also reflects some new packages necessary for testing - babel for transpiling JS files, svelte-jester for transpiling Svelte files, and happy-dom as mentioned above. A .babelrc config was added, and the Jest config file was updated to reflect these new packages.

Other Changes I also updated the webpack config for the regular script build to allow switching between development and production modes, and updated the scripts for this build in package.json appropriately.

Finally, I made a handful of small changes to existing files in the backed src folder - mostly adding comments for clarity, and doing some light refactoring around ensuring that functions that can be pure are pure, and trying to better adhere to the principle of single responsibility.

AnchiTeng commented 1 year ago

The testing script works.