Skip to content

Build unit tests specifically #26132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
dgp1130 opened this issue Oct 25, 2023 · 0 comments
Open

Build unit tests specifically #26132

dgp1130 opened this issue Oct 25, 2023 · 0 comments
Labels
area: @angular-devkit/build-angular feature: under consideration Feature request for which voting has completed and the request is now under consideration feature Issue that requests a new feature

Comments

@dgp1130
Copy link
Collaborator

dgp1130 commented Oct 25, 2023

Command

test

Description

From #25434 (comment).

One way Angular can more easily compose with other test tools in the ecosystem is to expose the build process for test files. Plugging in an arbitrary test runner or configuration can work much more smoothly when a user can build Angular's unit tests to a temporary directory and then execute a unit test runner on top of it. This gives full control over the test runner and its configuration (which may not otherwise integrate with Angular).

Describe the solution you'd like

There are three immediately obvious ways of doing this with various trade offs:

  1. ng build --tests - This would update the build target target (browser or application) to support building tests for an application. Unfortunately this builder doesn't actually know which tests you're trying to include or what additional test options you might have (test polyfills for example like zone.js/testing). Including test-specific concerns into the build target would break the abstraction it tries to provide (application builds an application, not tests).

  2. ng test --build-only - This is similar to the first, but shifts the responsibility to the test builder, which has a little more context about test options. It would need to support a user-specified outputPath. We could definitely expose that, though ng test --build-only comes dangerously close to what I call ng test --dont, where an option basically invalidates the point of the command and I'd very much like to avoid that.

  3. ng run build-tests - This approach separate building an application, building tests, and running tests in distinct builders like:

{
  "projects": {
    "my-app": {
      "architect": {
        // Builds the application itself.
        "build": {
          "builder": "@angular-devkit/build-angular:application"
        },

        // Builds tests of the application.
        "build-tests": {
          "builder": "@angular-devkit/build-angular:build-tests",
          "options": {
            "buildTarget": "my-app:build",
            "include": ["**/*.ts"],
            // Build options specific to tests...
          }
        }

        "test": {
          "builder": "@angular-devkit/build-angular:jest",
          "options": {
            "buildTestsTarget": "my-app:build-tests",
            // Jest options...
          }
        }
      }
    }
  }
}

This nicely separates the build, build for test, and test actions, meaning they can be run independently. ng test could build and test the application, while ng run build-tests would only perform the build step.

The unfortunate part of this is that it gets quite verbose and Architect is not well set up today to compose other builders in an easy way. Also build-tests doesn't really wrap build in this way, as it needs to modify the work done by the build target in a really awkward way which can lead to a lot of nuance.

Currently the exact shape of the built output for tests is an internal implementation detail, while this feature necessitates making that effectively public API. We'd need to figure out the exact contract of what this directory actually contains and how test tools should leverage it. For example, Jest needs to load polyfills in a very specific way so they are applied inside the VM for each test and we would need to make sure approaches like that are supported.

Describe alternatives you've considered

  1. Integrate with every notable test runner (hard to scale).

  2. Expose hooks for the build/test process for every supported test runner (hard to be flexible and opinionated at the same time).

  3. Build Angular application components like a library, defer the test compilation to another tool.

    Arguably build-tests shouldn't even build the **.spec.ts files, but rather build application components like a library which can be imported by a test compilation. We've talked about potentially replacing ng-packagr with a new library builder (congruent with the application builder). If this was somewhat decoupled from the APF format (which isn't needed for tests) we could potentially use that as the build-tests target. This could build all the **.spec.ts files, or potentially just build the **.ts files (with main.ts excluded). A separate compilation (whether also using this library builder or just calling tsc directly) could build the actual **.spec.ts files with a dependency on the pre-built **.ts files.

    This is actually how things are done inside Google, but we have a pretty comprehensive build system in Bazel to make that scale effectively. In an Angular CLI context, I expect this is probably being way too specific and nuanced with the build process to be useful. As much as I want things to work this way, I get that most users probably don't and it likely isn't worth the configuration and complexity cost.

@dgp1130 dgp1130 added feature Issue that requests a new feature feature: under consideration Feature request for which voting has completed and the request is now under consideration labels Oct 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: @angular-devkit/build-angular feature: under consideration Feature request for which voting has completed and the request is now under consideration feature Issue that requests a new feature
Projects
None yet
Development

No branches or pull requests

2 participants