Stryker/Angular6:从模板应用程序的标准@Component 中删除突变体
Stryker/Angular6: Remove mutants from standard @Component on template application
我已经用 Angular 6 创建了一个基本的模板应用程序,我正在尝试对其进行 Stryker 突变测试。在基本主页上:
import { Component } from '@angular/core';
/**
* Home Page Definition
*/
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss']
})
export class HomePage {}
我有这个页面的基本测试文件:
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HomePage } from './home.page';
/**
* Home Page Test File
*/
describe('HomePage', () => {
let component: HomePage;
let fixture: ComponentFixture<HomePage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [HomePage],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HomePage);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeDefined();
expect(component).toBeTruthy();
});
it('should be proper component', () => {
expect(component).toBeInstanceOf(HomePage);
});
});
虽然这通过并测试了主页将被创建,但我仍然有
.
在基本主页上,@Component 有 3 个字段,因为它们是文字文本,所以都生成变异幸存者。我不确定如何编写杀死这些变异幸存者的测试。
如果我无法编写测试来处理这种情况,Stryker 似乎没有一种方法可以忽略一段代码作为替代。
您可以测试组件实例的组件元数据注释,这在执行 TDD(测试驱动开发)时作为起点很好,但您应该能够快速将其替换为验证实际行为的适当测试。
请注意,即将进行的 Angular Ivy 内部重写将更改运行时组件元数据。
A StackBlitz demonstrating this spec
样式
/* host.page.scss */
:host {
display: block;
font-family: Georgia, serif;
}
模板
<!-- host.page.html -->
<p>app-home works!</p>
测试套件
// home.page.spec.ts
import { Component, DebugElement } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { HomePage } from './home.page';
type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T]
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>
type ComponentMetadata = Omit<Component, 'styleUrls' | 'templateUrl'>
@Component({
template: '<app-home></app-home>'
})
class TestHostComponent {}
/**
* Home Page Test File
*/
describe('HomePage', () => {
let component: HomePage;
let debugElement: DebugElement;
let hostFixture: ComponentFixture<TestHostComponent>;
let metadata: ComponentMetadata;
let nativeElement: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
HomePage,
TestHostComponent,
],
}).compileComponents();
}));
beforeEach(() => {
hostFixture = TestBed.createComponent(TestHostComponent);
debugElement = hostFixture.debugElement.query(By.css('app-home'));
component = debugElement.componentInstance;
nativeElement = debugElement.nativeElement;
metadata = component['__proto__'].constructor.__annotations__[0];
hostFixture.detectChanges();
});
it('should create', () => {
expect(component).toBeDefined();
expect(component).toBeTruthy();
});
it('should be proper component', () => {
expect(component instanceof HomePage).toBe(true, 'it must be a HomePage');
});
describe('metadata inspection', () => {
it('should have proper selector', () => {
const { selector } = metadata;
expect(selector).toBe('app-home');
});
it('should have template', () => {
const { template } = metadata;
expect(template).toContain('app-home works!');
});
it('should have styles', () => {
const { styles: [style] } = metadata;
expect(style).toContain('display:block');
expect(style).toContain('font-family:Georgia');
});
});
describe('shallow tests with host component', () => {
it('should have proper selector', () => {
expect(nativeElement.tagName).toMatch(/app\-home/i);
});
it('should have template', () => {
expect(nativeElement.innerText).toContain('app-home works!');
});
it('should have styles', () => {
const styles: CSSStyleDeclaration = getComputedStyle(nativeElement);
expect(styles.display).toBe('block');
expect(styles.fontFamily.startsWith('Georgia'))
.toBe(true, 'it should use the expected font family')
});
});
});
我已经用 Angular 6 创建了一个基本的模板应用程序,我正在尝试对其进行 Stryker 突变测试。在基本主页上:
import { Component } from '@angular/core';
/**
* Home Page Definition
*/
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss']
})
export class HomePage {}
我有这个页面的基本测试文件:
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HomePage } from './home.page';
/**
* Home Page Test File
*/
describe('HomePage', () => {
let component: HomePage;
let fixture: ComponentFixture<HomePage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [HomePage],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HomePage);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeDefined();
expect(component).toBeTruthy();
});
it('should be proper component', () => {
expect(component).toBeInstanceOf(HomePage);
});
});
虽然这通过并测试了主页将被创建,但我仍然有
在基本主页上,@Component 有 3 个字段,因为它们是文字文本,所以都生成变异幸存者。我不确定如何编写杀死这些变异幸存者的测试。
如果我无法编写测试来处理这种情况,Stryker 似乎没有一种方法可以忽略一段代码作为替代。
您可以测试组件实例的组件元数据注释,这在执行 TDD(测试驱动开发)时作为起点很好,但您应该能够快速将其替换为验证实际行为的适当测试。
请注意,即将进行的 Angular Ivy 内部重写将更改运行时组件元数据。
A StackBlitz demonstrating this spec
样式
/* host.page.scss */
:host {
display: block;
font-family: Georgia, serif;
}
模板
<!-- host.page.html -->
<p>app-home works!</p>
测试套件
// home.page.spec.ts
import { Component, DebugElement } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { HomePage } from './home.page';
type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T]
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>
type ComponentMetadata = Omit<Component, 'styleUrls' | 'templateUrl'>
@Component({
template: '<app-home></app-home>'
})
class TestHostComponent {}
/**
* Home Page Test File
*/
describe('HomePage', () => {
let component: HomePage;
let debugElement: DebugElement;
let hostFixture: ComponentFixture<TestHostComponent>;
let metadata: ComponentMetadata;
let nativeElement: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
HomePage,
TestHostComponent,
],
}).compileComponents();
}));
beforeEach(() => {
hostFixture = TestBed.createComponent(TestHostComponent);
debugElement = hostFixture.debugElement.query(By.css('app-home'));
component = debugElement.componentInstance;
nativeElement = debugElement.nativeElement;
metadata = component['__proto__'].constructor.__annotations__[0];
hostFixture.detectChanges();
});
it('should create', () => {
expect(component).toBeDefined();
expect(component).toBeTruthy();
});
it('should be proper component', () => {
expect(component instanceof HomePage).toBe(true, 'it must be a HomePage');
});
describe('metadata inspection', () => {
it('should have proper selector', () => {
const { selector } = metadata;
expect(selector).toBe('app-home');
});
it('should have template', () => {
const { template } = metadata;
expect(template).toContain('app-home works!');
});
it('should have styles', () => {
const { styles: [style] } = metadata;
expect(style).toContain('display:block');
expect(style).toContain('font-family:Georgia');
});
});
describe('shallow tests with host component', () => {
it('should have proper selector', () => {
expect(nativeElement.tagName).toMatch(/app\-home/i);
});
it('should have template', () => {
expect(nativeElement.innerText).toContain('app-home works!');
});
it('should have styles', () => {
const styles: CSSStyleDeclaration = getComputedStyle(nativeElement);
expect(styles.display).toBe('block');
expect(styles.fontFamily.startsWith('Georgia'))
.toBe(true, 'it should use the expected font family')
});
});
});