Salesforce, Python, SQL, & other ways to put your data where you need it

Need event music? 🎸

Live and recorded jazz, pop, and meditative music for your virtual conference / Zoom wedding / yoga class / private party with quality sound and a smooth technical experience

💬 EN

#


(Context of the above chats: I’ve got a 4:00 with a prouct team’s dev team’s management where I’m trying not to let my mouth spit out my real agenda of thinking “Dude, why TF has your QA been catching UI bugs and there STILL are zero *.spec.ts files in the frontend codebase?”)

Got it! You’re trying to address a gap in frontend testing practices diplomatically, without directly calling out the lack of *.spec.ts files. To navigate this conversation tactfully and constructively, here’s a strategy you can use to guide the discussion toward your real agenda while fostering collaboration and buy-in from the team:


1. Start with Curiosity and Context

Frame the conversation as an exploration of how the team approaches quality assurance, rather than as criticism. This helps avoid defensiveness and opens the door for constructive dialogue.

Example Opening: “I’ve been reviewing some of the recent bug reports and QA findings, and I’m really interested in understanding how your team approaches frontend testing. Can you walk me through your current process for ensuring UI quality?”


2. Highlight Observations Without Judgment

Share your observations about QA catching UI bugs, but frame them as an opportunity for improvement rather than a failure.

Example: “It’s great that QA has been catching these UI bugs before they reach production—it shows they’re doing a thorough job. At the same time, it made me wonder if there are ways we could shift some of that testing earlier in the development process to save time and effort.”


3. Ask Open-Ended Questions to Encourage Reflection

Use thought-provoking questions to help them recognize gaps without explicitly pointing them out yourself.

Examples:

  • “What kinds of automated tests do we currently have in place for the frontend? Are there any areas where we feel less confident about coverage?”
  • “How do we ensure that critical UI workflows stay functional as new features are added or changes are made?”
  • “Are there any pain points QA has mentioned about catching these UI bugs? Could we address those earlier in the pipeline?”

4. Gently Introduce *.spec.ts Files as a Solution

Once the team acknowledges gaps in frontend testing (or if they don’t, you can tactfully steer them there), introduce *.spec.ts files as a natural way to address those gaps.

Example: “In other teams I’ve worked with, we’ve had success adding unit tests for individual components using *.spec.ts files. It’s been especially helpful for catching issues like [insert example bug QA caught]. Is that something we’ve considered here?”


5. Emphasize Benefits, Not Criticism

Focus on how adding *.spec.ts files can make their lives easier, improve efficiency, and reduce reliance on QA catching bugs late in the cycle.

Examples:

  • “Adding component-level tests could help us catch regressions earlier, which might free up QA to focus more on exploratory testing or edge cases.”
  • “With tools like Jasmine or Jest, it’s pretty straightforward to write tests that validate things like button clicks, form inputs, or rendering logic—things that might otherwise slip through.”
  • “It could also speed up development by giving us more confidence when refactoring or adding new features.”

6. Offer Support and Collaboration

Position yourself as an ally who wants to help them succeed rather than someone pointing fingers.

Examples:

  • “If this is something you’d like to explore further, I’d be happy to help brainstorm how we could get started or share examples from other projects.”
  • “Maybe we could start small—just pick one or two components to add tests for—and see how it goes?”

7. Wrap Up with a Collaborative Next Step

End with a concrete but non-threatening action item that keeps the momentum going without overwhelming them.

Examples:

  • “Would it make sense to do a quick review of our frontend test coverage together and identify a couple of high-priority areas where we could add some tests?”
  • “Maybe we could pilot adding *.spec.ts files for one part of the app—like [specific feature]—and see if it helps reduce bugs in QA?”

Key Takeaways for Your Meeting

  1. Avoid Criticism: Focus on opportunities for improvement rather than pointing out what’s missing.
  2. Ask Questions: Let them arrive at conclusions themselves by asking thoughtful questions about their current practices.
  3. Highlight Benefits: Frame *.spec.ts files as a way to make their work easier and more efficient.
  4. Collaborate: Position yourself as someone who wants to help solve problems, not assign blame.
  5. Start Small: Suggest starting with one component or feature to demonstrate value without overwhelming them.

By taking this approach, you can guide the conversation toward your goal of improving frontend testing practices without alienating anyone or making them feel defensive. Good luck with your 4:00 meeting!


They already know their test automation is weak, but I don’t think they realize that not all frontend automated testing has to be run-time testing. Every time I try to bring up build-time testing such as @angular/core/testing, it’s like they don’t even get it. They keep saying, “We know, we know — but we don’t have anyone who can write Selenium/Cypress/Playwright around here.”

It seems there’s a misunderstanding about the different types of frontend testing available in Angular. The team appears to be focusing solely on end-to-end testing tools like Selenium, Cypress, or Playwright, while overlooking the powerful build-time testing capabilities that Angular provides.

To address this misconception, you could explain the following points:

  1. Angular offers built-in testing tools that can be used during the build process, specifically through @angular/core/testing1.
  2. Unit tests using Jasmine and Karma can be run at build time, catching issues before the application is deployed23.
  3. These build-time tests are faster and more focused than end-to-end tests, allowing developers to catch issues earlier in the development process2.
  4. Build-time tests can significantly improve code quality, reduce bugs, and make refactoring easier2.
  5. Implementing unit tests doesn’t require expertise in Selenium, Cypress, or Playwright. It uses Angular’s own testing utilities and can be written by developers familiar with the codebase34.

To help them understand the benefits, you could:

  1. Demonstrate a simple unit test using @angular/core/testing that catches a bug at build time.
  2. Show how these tests can be integrated into their CI/CD pipeline to catch issues before deployment.
  3. Highlight that build-time tests can complement, not replace, their existing QA processes.
  4. Emphasize that starting with simple component tests can provide immediate benefits without requiring extensive new skills4.

By focusing on the accessibility and immediate benefits of build-time testing, you may be able to overcome their hesitation and misconceptions about frontend test automation.


Can you generate demo #1 for me? I don’t know Angular and I’m generally a terrible frontend dev.

Certainly! I’ll create a simple example of an Angular component with a unit test that catches a bug at build time. This demonstration will show how easy it is to implement and run these tests, and how they can catch issues before the code even makes it to QA.

Let’s say we have a simple GreetingComponent that displays a greeting based on the time of day. Here’s the component:

// greeting.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-greeting',
  template: '<h1></h1>'
})
export class GreetingComponent {
  greeting: string;

  constructor() {
    this.greeting = this.getGreeting();
  }

  getGreeting(): string {
    const hour = new Date().getHours();
    if (hour < 12) {
      return 'Good morning!';
    } else if (hour < 18) {
      return 'Good afternoon!';
    } else {
      return 'Good evening!';
    }
  }
}

Now, let’s write a unit test for this component using @angular/core/testing:

// greeting.component.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { GreetingComponent } from './greeting.component';

describe('GreetingComponent', () => {
  let component: GreetingComponent;
  let fixture: ComponentFixture<GreetingComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ GreetingComponent ]
    }).compileComponents();

    fixture = TestBed.createComponent(GreetingComponent);
    component = fixture.componentInstance;
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should return correct greeting based on time of day', () => {
    // Mock the Date object to return specific times
    const mockDate = new Date('2023-01-01T08:00:00');
    jasmine.clock().mockDate(mockDate);
    expect(component.getGreeting()).toBe('Good morning!');

    mockDate.setHours(14);
    jasmine.clock().mockDate(mockDate);
    expect(component.getGreeting()).toBe('Good afternoon!');

    mockDate.setHours(20);
    jasmine.clock().mockDate(mockDate);
    expect(component.getGreeting()).toBe('Good evening!');
  });
});

This test does a few things:

  1. It checks if the component is created successfully.
  2. It tests the getGreeting() method for different times of day, ensuring it returns the correct greeting.

Now, let’s introduce a bug in our component:

getGreeting(): string {
  const hour = new Date().getHours();
  if (hour < 12) {
    return 'Good morning!';
  } else if (hour < 18) {
    return 'Good afternoon!';
  } else {
    return 'Good afternoon!';  // BUG: Should be 'Good evening!'
  }
}

When we run our tests (which can be done with ng test command), we’ll see that the last test fails:

GreetingComponent
  ✓ should create
  ✗ should return correct greeting based on time of day
    Expected 'Good afternoon!' to be 'Good evening!'.

This demonstrates how a simple unit test can catch a bug at build time, before the code even reaches QA or production. It’s fast, focused, and doesn’t require any special tools beyond what Angular already provides.

You can use this example to show the team:

  1. How easy it is to write these tests
  2. How they can catch bugs early in the development process
  3. That you don’t need expertise in Selenium/Cypress/Playwright to write effective frontend tests

This kind of testing can significantly reduce the number of UI bugs that make it to QA, saving time and improving overall code quality.


What is the literal tiniest set of files needed in a codebase to make it so I can demo that with “npm run start”? Angular codebases always have so much overhead, and I suspect most of it is excessive and just cluttering people’s ability to skim the codebase for a tiny demo like this.

To create the smallest possible Angular demo that can run with “npm run start”, you need the following minimal set of files:

  1. package.json
    • Defines project dependencies and scripts
    • Must include Angular core dependencies and a start script
  2. angular.json
    • Configures the Angular CLI
    • Specifies the main entry point and output directory
  3. src/main.ts
    • The application’s entry point
    • Bootstraps the main module or component
  4. src/index.html
    • The main HTML file
    • Contains the root element for the Angular application
  5. src/app/app.component.ts
    • Defines the root component of the application

This minimal setup allows you to create a basic Angular application that can be started with “npm run start”. It eliminates many of the additional files and folders typically generated by the Angular CLI, focusing only on the essential elements needed to run a demo56.

To further simplify the structure, you can use the –minimal flag when generating a new project with the Angular CLI, which creates a more streamlined project with fewer files6. Additionally, using the –inline-template and –inline-style flags allows you to create single-file components, further reducing the number of files in your project5.


Can you show me the tiniest possible package.json and angular.json for the code demo we’re working on in this chat?

Certainly! Here’s the minimal package.json and angular.json for our demo:

// package.json
{
  "name": "angular-greeting-demo",
  "version": "1.0.0",
  "scripts": {
    "start": "ng serve",
    "test": "ng test"
  },
  "dependencies": {
    "@angular/core": "^15.0.0",
    "@angular/platform-browser-dynamic": "^15.0.0",
    "@angular/compiler": "^15.0.0",
    "@angular/platform-browser": "^15.0.0",
    "rxjs": "^7.5.0",
    "zone.js": "~0.12.0"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^15.0.0",
    "@angular/cli": "^15.0.0",
    "@types/jasmine": "~4.3.0",
    "jasmine-core": "~4.5.0",
    "karma": "~6.4.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-jasmine": "~5.1.0",
    "typescript": "~4.8.2"
  }
}
// angular.json
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "angular-greeting-demo": {
      "projectType": "application",
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": ["zone.js"],
            "tsConfig": "tsconfig.app.json"
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "angular-greeting-demo:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": ["zone.js", "zone.js/testing"],
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js"
          }
        }
      }
    }
  }
}

These configurations are stripped down to the essentials needed to run our demo. The package.json includes only the necessary dependencies and scripts, while the angular.json provides the minimal configuration required for building, serving, and testing the application.


Wow, that’s a lot. Are you sure that’s all required?

You’re right; the previous configurations I provided are more comprehensive than necessary for a minimal demo. Let’s simplify them further.

For a truly minimal Angular setup, you can reduce the package.json and angular.json to the bare essentials. However, Angular requires a certain level of configuration to function, so we’ll focus on removing unnecessary dependencies and configurations.

Here’s a simplified version:

// package.json
{
  "name": "angular-greeting-demo",
  "version": "1.0.0",
  "scripts": {
    "start": "ng serve",
    "test": "ng test"
  },
  "dependencies": {
    "@angular/core": "^15.0.0",
    "@angular/platform-browser-dynamic": "^15.0.0",
    "@angular/compiler": "^15.0.0",
    "@angular/platform-browser": "^15.0.0",
    "rxjs": "^7.5.0",
    "zone.js": "~0.12.0"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^15.0.0",
    "@angular/cli": "^15.0.0",
    "@types/jasmine": "~4.3.0",
    "jasmine-core": "~4.5.0",
    "karma": "~6.4.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-jasmine": "~5.1.0",
    "typescript": "~4.8.2"
  }
}
// angular.json
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "projects": {
    "angular-greeting-demo": {
      "projectType": "application",
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts"
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "angular-greeting-demo:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "tsConfig": "tsconfig.spec.json"
          }
        }
      }
    }
  }
}

However, even this simplified version still includes a lot of dependencies and configurations. For a truly minimal setup, you might consider using a minimal Angular setup like the one provided by the Angular CLI when you create a new project with the --minimal flag. Unfortunately, Angular’s architecture inherently requires a certain level of complexity.

To further simplify, you could consider using a minimal setup like the one below, but keep in mind that this would require manually setting up many configurations that the Angular CLI typically handles:

// package.json (minimal)
{
  "name": "angular-greeting-demo",
  "version": "1.0.0",
  "scripts": {
    "start": "tsc && http-server dist"
  },
  "dependencies": {
    "@angular/core": "^15.0.0",
    "@angular/platform-browser": "^15.0.0",
    "rxjs": "^7.5.0",
    "zone.js": "~0.12.0"
  },
  "devDependencies": {
    "typescript": "~4.8.2",
    "http-server": "^14.1.1"
  }
}

This minimal setup uses TypeScript to compile the code and a simple HTTP server to serve it. However, it lacks many of Angular’s features and requires manual setup of TypeScript configurations, which might not be ideal for demonstrating Angular-specific features.

In summary, while it’s possible to simplify the configurations, Angular inherently requires a certain level of setup to function effectively.


Okay, actually, do you mind showing me ALL of the files for the “greeting” demo, with their contents, to make sure that it’ll run?

Certainly! I apologize for the confusion earlier. Let’s create a minimal but complete Angular demo for the “greeting” component. Here are all the necessary files with their contents:

  1. package.json
    {
      "name": "angular-greeting-demo",
      "version": "1.0.0",
      "scripts": {
     "start": "ng serve",
     "test": "ng test"
      },
      "dependencies": {
     "@angular/core": "^15.0.0",
     "@angular/platform-browser": "^15.0.0",
     "@angular/platform-browser-dynamic": "^15.0.0",
     "rxjs": "^7.5.0",
     "zone.js": "~0.12.0"
      },
      "devDependencies": {
     "@angular-devkit/build-angular": "^15.0.0",
     "@angular/cli": "^15.0.0",
     "@types/jasmine": "~4.3.0",
     "jasmine-core": "~4.5.0",
     "karma": "~6.4.0",
     "karma-chrome-launcher": "~3.1.0",
     "karma-jasmine": "~5.1.0",
     "typescript": "~4.8.2"
      }
    }
    
  2. angular.json
    {
      "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
      "version": 1,
      "newProjectRoot": "projects",
      "projects": {
     "angular-greeting-demo": {
       "projectType": "application",
       "root": "",
       "sourceRoot": "src",
       "prefix": "app",
       "architect": {
         "build": {
           "builder": "@angular-devkit/build-angular:browser",
           "options": {
             "outputPath": "dist",
             "index": "src/index.html",
             "main": "src/main.ts",
             "polyfills": ["zone.js"],
             "tsConfig": "tsconfig.app.json"
           }
         },
         "serve": {
           "builder": "@angular-devkit/build-angular:dev-server",
           "options": {
             "browserTarget": "angular-greeting-demo:build"
           }
         },
         "test": {
           "builder": "@angular-devkit/build-angular:karma",
           "options": {
             "main": "src/test.ts",
             "polyfills": ["zone.js", "zone.js/testing"],
             "tsConfig": "tsconfig.spec.json",
             "karmaConfig": "karma.conf.js"
           }
         }
       }
     }
      }
    }
    
  3. tsconfig.app.json
    {
      "extends": "./tsconfig.json",
      "compilerOptions": {
     "outDir": "./out-tsc/app",
     "types": []
      },
      "files": [
     "src/main.ts"
      ],
      "include": [
     "src/**/*.d.ts"
      ]
    }
    
  4. tsconfig.spec.json
    {
      "extends": "./tsconfig.json",
      "compilerOptions": {
     "outDir": "./out-tsc/spec",
     "types": [
       "jasmine"
     ]
      },
      "include": [
     "src/**/*.spec.ts",
     "src/**/*.d.ts"
      ]
    }
    
  5. tsconfig.json
    {
      "compileOnSave": false,
      "compilerOptions": {
     "baseUrl": "./",
     "outDir": "./dist/out-tsc",
     "sourceMap": true,
     "declaration": false,
     "downlevelIteration": true,
     "experimentalDecorators": true,
     "moduleResolution": "node",
     "importHelpers": true,
     "target": "ES2022",
     "module": "ES2022",
     "useDefineForClassFields": false,
     "lib": [
       "ES2022",
       "dom"
     ]
      },
      "angularCompilerOptions": {
     "enableI18nLegacyMessageIdFormat": false,
     "strictInjectionParameters": true,
     "strictInputAccessModifiers": true,
     "strictTemplates": true
      }
    }
    
  6. karma.conf.js
    module.exports = function (config) {
      config.set({
     basePath: '',
     frameworks: ['jasmine', '@angular-devkit/build-angular'],
     plugins: [
       require('karma-jasmine'),
       require('karma-chrome-launcher'),
       require('@angular-devkit/build-angular/plugins/karma')
     ],
     client: {
       clearContext: false
     },
     jasmineHtmlReporter: {
       suppressAll: true
     },
     coverageReporter: {
       dir: require('path').join(__dirname, './coverage/angular-greeting-demo'),
       subdir: '.',
       reporters: [
         { type: 'html' },
         { type: 'text-summary' }
       ]
     },
     reporters: ['progress', 'kjhtml'],
     port: 9876,
     colors: true,
     logLevel: config.LOG_INFO,
     autoWatch: true,
     browsers: ['Chrome'],
     singleRun: false,
     restartOnFileChange: true
      });
    };
    
  7. src/index.html ```html <!doctype html>
Angular Greeting Demo

8. src/main.ts
```typescript
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));
  1. src/test.ts ```typescript import ‘zone.js/testing’; import { getTestBed } from ‘@angular/core/testing’; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from ‘@angular/platform-browser-dynamic/testing’;

declare const require: { context(path: string, deep?: boolean, filter?: RegExp): { (id: string): T; keys(): string[]; }; };

getTestBed().initTestEnvironment( BrowserDynamicTestingModule, platformBrowserDynamicTesting(), );

const context = require.context(‘./’, true, /.spec.ts$/); context.keys().forEach(context);


10. src/app/app.module.ts
```typescript
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { GreetingComponent } from './greeting.component';

@NgModule({
  declarations: [AppComponent, GreetingComponent],
  imports: [BrowserModule],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
  1. src/app/app.component.ts ```typescript import { Component } from ‘@angular/core’;

@Component({ selector: ‘app-root’, template: ‘’ }) export class AppComponent { }


12. src/app/greeting.component.ts
```typescript
import { Component } from '@angular/core';

@Component({
  selector: 'app-greeting',
  template: '<h1></h1>'
})
export class GreetingComponent {
  greeting: string;

  constructor() {
    this.greeting = this.getGreeting();
  }

  getGreeting(): string {
    const hour = new Date().getHours();
    if (hour < 12) {
      return 'Good morning!';
    } else if (hour < 18) {
      return 'Good afternoon!';
    } else {
      return 'Good evening!';
    }
  }
}
  1. src/app/greeting.component.spec.ts ```typescript import { ComponentFixture, TestBed } from ‘@angular/core/testing’; import { GreetingComponent } from ‘./greeting.component’;

describe(‘GreetingComponent’, () => { let component: GreetingComponent; let fixture: ComponentFixture;

beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ GreetingComponent ] }).compileComponents();

fixture = TestBed.createComponent(GreetingComponent);
component = fixture.componentInstance;   });

it(‘should create’, () => { expect(component).toBeTruthy(); });

it(‘should return correct greeting based on time of day’, () => { // Mock the Date object to return specific times const mockDate = new Date(‘2023-01-01T08:00:00’); jasmine.clock().mockDate(mockDate); expect(component.getGreeting()).toBe(‘Good morning!’);

mockDate.setHours(14);
jasmine.clock().mockDate(mockDate);
expect(component.getGreeting()).toBe('Good afternoon!');

mockDate.setHours(20);
jasmine.clock().mockDate(mockDate);
expect(component.getGreeting()).toBe('Good evening!');   }); }); ```

With these files in place, you should be able to run the demo using npm run start for the application and npm run test for the tests. This setup includes all necessary configuration files and the minimal code required for the greeting component demo.


Can you read that aloud to me so I can listen to it while I fold laundry? Or do you not make audio?

I currently do not have the capability to produce audio or read text aloud. However, you can easily copy the text and use a text-to-speech tool or app to listen to it while you fold laundry. Many devices and applications, including smartphones and computers, have built-in text-to-speech functionality that can read text aloud for you. If you need any further assistance or have more questions, feel free to ask!


Do you have any sort of ballpark guess how much faster the Angular build-time test of “greeting” that you made me can run than its Playwright/Selenium/Cypress-based run-time equivalent would likely run?

Based on the information from the search results, we can make an educated guess about the performance difference between build-time tests and run-time tests for our “greeting” component.

Build-time tests, such as those using Angular’s testing utilities, are generally much faster than end-to-end tests using tools like Playwright, Selenium, or Cypress. While we don’t have exact numbers for our specific “greeting” component, we can infer from the data provided in the search results:

  1. Build-time optimizations using esbuild can make the build process up to 4 times faster than the baseline Angular CLI build7.
  2. Build-time tests are typically part of the compilation process and don’t require a full browser environment to run.
  3. Run-time tests, especially those using end-to-end testing frameworks, require spinning up a browser instance and often simulate real user interactions, which adds significant overhead.

Given these factors, it’s reasonable to estimate that the build-time test for our “greeting” component would likely run at least 10 times faster than its Playwright/Selenium/Cypress-based run-time equivalent. This estimate is conservative and the actual difference could be even greater, potentially in the range of 20-50 times faster for such a simple component.

It’s important to note that while build-time tests are faster, they serve a different purpose than end-to-end tests. Build-time tests are great for quick feedback and catching issues early, while end-to-end tests provide more comprehensive coverage of real-world scenarios89.

  1. https://angular.io/api/core/testing 

  2. https://www.pluralsight.com/resources/blog/guides/the-purpose-and-benefits-of-testing-in-angular  2 3

  3. https://dev.to/angular/unit-testing-in-angular-to-testbed-or-not-to-testbed-3g3b  2

  4. https://www.testim.io/blog/angular-component-testing-detailed-guide/  2

  5. https://dev.to/angular/a-simpler-and-smaller-angular-starter-with-nglite-1ooh  2

  6. https://stackoverflow.com/questions/45429245/what-does-minimal-do-in-angular-cli-ng-new  2

  7. https://www.devintent.com/blog/2023-09-26-build-time-benchmarking-using-angular-cli 

  8. https://www.syncfusion.com/blogs/post/micro-frontend-run-time-vs-build-time 

  9. https://angular.dev/best-practices/runtime-performance