diff --git a/README.md b/README.md
index f59d056c..01cb7da3 100644
--- a/README.md
+++ b/README.md
@@ -65,8 +65,8 @@ The tutorial consists of the following steps. To start, just open the first link
- **[Step 24: Sorting and Grouping](steps/24/README.md "To make our list of invoices even more user-friendly, we sort it alphabetically instead of just showing the order from the data model. Additionally, we introduce groups and add the company that ships the products so that the data is easier to consume.")** ([π Live Preview](https://sap-samples.github.io/ui5-typescript-walkthrough/step-24/index-cdn.html) \| [π₯ Download Solution](https://sap-samples.github.io/ui5-typescript-walkthrough/ui5-typescript-walkthrough-step-24.zip))
- **[Step 25: Remote OData Service](steps/25/README.md "So far we have worked with local JSON data, but now we will access a real OData service to visualize remote data.")** (π Live Preview *unfeasible* \| [π₯ Download Solution](https://sap-samples.github.io/ui5-typescript-walkthrough/ui5-typescript-walkthrough-step-25.zip))
- **[Step 26: Mock Server Configuration](steps/26/README.md "We just ran our app against a real service, but for developing and testing our app we do not want to rely on the availability of the βrealβ service or put additional load on the system where the data service is located.")** ([π Live Preview](https://sap-samples.github.io/ui5-typescript-walkthrough/step-26/test/mockServer-cdn.html) \| [π₯ Download Solution](https://sap-samples.github.io/ui5-typescript-walkthrough/ui5-typescript-walkthrough-step-26.zip))
-- **[Step 27: Unit Test with QUnit](steps/27/README.md "Now that we have a test folder in the app, we can start to increase our test coverage. ")** ([π Live Preview](https://sap-samples.github.io/ui5-typescript-walkthrough/step-27/test/unit/unitTests-cdn.qunit.html) \| [π₯ Download Solution](https://sap-samples.github.io/ui5-typescript-walkthrough/ui5-typescript-walkthrough-step-27.zip))
-- **[Step 28: Integration Test with OPA](steps/28/README.md "If we want to test interaction patterns or more visual features of our app, we can also write an integration test. ")** ([π Live Preview](https://sap-samples.github.io/ui5-typescript-walkthrough/step-28/test/integration/opaTests-cdn.qunit.html) \| [π₯ Download Solution](https://sap-samples.github.io/ui5-typescript-walkthrough/ui5-typescript-walkthrough-step-28.zip))
+- **[Step 27: Unit Test with QUnit](steps/27/README.md "Now that we have a test folder in the app, we can start to increase our test coverage. ")** ([π Live Preview](https://sap-samples.github.io/ui5-typescript-walkthrough/step-27/test/Test.cdn.qunit.html?testsuite=test-resources/ui5/walkthrough/testsuite.cdn.qunit&test=unit/unitTests) \| [π₯ Download Solution](https://sap-samples.github.io/ui5-typescript-walkthrough/ui5-typescript-walkthrough-step-27.zip))
+- **[Step 28: Integration Test with OPA](steps/28/README.md "If we want to test interaction patterns or more visual features of our app, we can also write an integration test. ")** ([π Live Preview](https://sap-samples.github.io/ui5-typescript-walkthrough/step-28/test/Test.cdn.qunit.html?testsuite=test-resources/ui5/walkthrough/testsuite.cdn.qunit&test=integration/opaTests) \| [π₯ Download Solution](https://sap-samples.github.io/ui5-typescript-walkthrough/ui5-typescript-walkthrough-step-28.zip))
- **[Step 29: Debugging Tools](steps/29/README.md "Even though we have added a basic test coverage in the previous steps, it seems like we accidentally broke our app, because it does not display prices to our invoices anymore. We need to debug the issue and fix it before someone finds out.")** (*code remains unchanged from the previous step*)
- **[Step 30: Routing and Navigation](steps/30/README.md "So far, we have put all app content on one single page. As we add more and more features, we want to split the content and put it on separate pages.")** ([π Live Preview](https://sap-samples.github.io/ui5-typescript-walkthrough/step-30/test/mockServer-cdn.html) \| [π₯ Download Solution](https://sap-samples.github.io/ui5-typescript-walkthrough/ui5-typescript-walkthrough-step-30.zip))
- **[Step 31: Routing with Parameters](steps/31/README.md "We can now navigate between the overview and the detail page, but the actual item that we selected in the overview is not displayed on the detail page yet. A typical use case for our app is to show additional information for the selected item on the detail page. ")** ([π Live Preview](https://sap-samples.github.io/ui5-typescript-walkthrough/step-31/test/mockServer-cdn.html) \| [π₯ Download Solution](https://sap-samples.github.io/ui5-typescript-walkthrough/ui5-typescript-walkthrough-step-31.zip))
diff --git a/steps/01/README.md b/steps/01/README.md
index 72132ead..493ba4ee 100644
--- a/steps/01/README.md
+++ b/steps/01/README.md
@@ -57,7 +57,7 @@ In our webapp folder, we create a new HTML file named `index.html` and copy the
### webapp/manifest.json \(New\)
-The manifest file, also known as the "descriptor" or "app descriptor," serves as a crucial configuration file for applications, components, and libraries. Stored in the `webapp` folder, this file is read by OpenUI5 to instantiate a component. Although we haven't created a component yet (which is part of [Step 9: COmponent Configuration](../09/README.md)), we need to create the app descriptor already now, because UI5 Tooling , whichwe intend to use for development, also requires an app descriptor.
+The manifest file, also known as the "descriptor" or "app descriptor," serves as a crucial configuration file for applications, components, and libraries. Stored in the `webapp` folder, this file is read by OpenUI5 to instantiate a component. Although we haven't created a component yet (which is part of [Step 9: Component Configuration](../09/README.md)), we need to create the app descriptor already now, because UI5 Tooling , whichwe intend to use for development, also requires an app descriptor.
Hence, we create a new file called `manifest.json` in the webapp folder and define its essential attributes:
diff --git a/steps/27/README.md b/steps/27/README.md
index 81addb30..60e83b46 100644
--- a/steps/27/README.md
+++ b/steps/27/README.md
@@ -17,7 +17,7 @@ Actually, every feature that we added to the app so far, would require a separat
*A unit test for our formatters is now available*
-You can access the live preview by clicking on this link: [π Live Preview of Step 27](https://sap-samples.github.io/ui5-typescript-walkthrough/step-27/test/unit/unitTests-cdn.qunit.html).
+You can access the live preview by clicking on this link: [π Live Preview of Step 27](https://sap-samples.github.io/ui5-typescript-walkthrough/step-27/test/Test.cdn.qunit.html?testsuite=test-resources/ui5/walkthrough/testsuite.cdn.qunit&test=unit/unitTests).
To download the solution for this step as a zip file, just choose the link here: [π₯ Download Solution for Step 27](https://sap-samples.github.io/ui5-typescript-walkthrough/ui5-typescript-walkthrough-step-27.zip).
@@ -40,10 +40,13 @@ The new formatter file just contains one QUnit module for our formatter function
Finally, we perform our assertions. We check each branch of the formatter logic by invoking the isolated formatter function with the values that we expect in the data model \(`A`, `B`, `C`, and everything else\). We strictly compare the result of the formatter function with the hard-coded strings that we expect from the resource bundle and give a meaningful error message if the test should fail.
+> π **Note:**
+> Test code needs to import modules under test (i.e. productive code) via their full namespace (in our case `ui5/walkthrough/`), not via relative paths as test code uses a different namespace (`test-resources/ui5/walkthrough/`).
+
```ts
import ResourceModel from "sap/ui/model/resource/ResourceModel";
import Controller from "sap/ui/core/mvc/Controller";
-import formatter from "../../../model/formatter";
+import formatter from "ui5/walkthrough/model/formatter";
QUnit.module("Formatting function", {});
@@ -82,79 +85,124 @@ QUnit.test("Should return the translated texts", (assert) => {
### webapp/test/unit/unitTests.qunit.ts \(New\)
We create a new `unitTests.qunit.ts` file under `webapp/test/unit/`.
-This script loads and executes our formatter test. Before the QUnit test execution can be started we need to wait until the Core has been booted. Therefore, you need to disable the autostart `QUnit.config.autostart = false;`, require the `sap/ui/core/Core` module and use `Core.ready()` to wait until the Core has booted and then you can start the QUnit tests with `QUnit.start()`.
+This module will serve as the entry point for all our unit tests. It will be referenced in the test suite that we will set up later on.
+
+Inside the `unitTests.qunit.ts` file, we import the unit test for the custom formatter. This ensures that any tests related to the custom formatter functionality will be included when running our unit tests.
```ts
-/* @sapUiRequire */
-QUnit.config.autostart = false;
-
-// import all your QUnit tests here
-void Promise.all([
- import("sap/ui/core/Core"), // required to wait until Core has booted to start the QUnit tests
- import("ui5/walkthrough/test/unit/model/formatter"),
-]).then(([{default: Core}]) => Core.ready()).then(() => {
- QUnit.start();
-});
+import "./model/formatter";
```
-> π **Note:**
-> The annotation `@sapUiRequire` instructs the UI5 TypeScript transpilation process (executed by `ui5-tooling-transpile`) to use `sap.ui.require` instead of `sap.ui.define` for the transpiled module. This allows to load the module via a `
+ >
+
+