Optimize Component tests; Fix e2e execution

unit-test
Florian Hartwich 2017-04-15 23:23:21 +02:00
parent 704f426eea
commit 38a53b4001
9 changed files with 76 additions and 59 deletions

View File

@ -13,6 +13,7 @@ export class TaskEditPage extends AbstractHeaderPage {
assigneeName = element(by.id('assignee_name'));
assigneeEmail = element(by.id('assignee_email'));
saveButton = element(by.id('save'));
cancelButton = element(by.id('cancel'));
constructor(newTask: boolean) {
super();
@ -56,7 +57,12 @@ export class TaskEditPage extends AbstractHeaderPage {
return new TaskOverviewPage;
}
validateInput(elementId: string, value: string) {
cancelSubmitTask() : TaskOverviewPage {
this.cancelButton.click();
return new TaskOverviewPage();
}
static validateInput(elementId: string, value: string) {
const input = element(by.id(elementId));
expect(input.getAttribute('value')).toBe(value);
}

View File

@ -16,6 +16,8 @@ describe('Edit Task Form', function () {
}
};
const newTitle = 'Ersten Prototyp mit Angular 4.0 entwickelt';
it('should load task with its values in edit form', () => {
browser.get('/tasks');
const taskOverviewPage = new TaskOverviewPage;
@ -23,16 +25,15 @@ describe('Edit Task Form', function () {
const taskEditPage = taskOverviewPage.clickTask(dbTask.title);
// check for correct url - test input field values
taskEditPage.validateCurrentUrl('tasks/edit/' + dbTask.id);
taskEditPage.validateInput('title', dbTask.title);
taskEditPage.validateInput('description', dbTask.description);
taskEditPage.validateInput('state', dbTask.state);
taskEditPage.validateInput('assignee_name', dbTask.assignee['name'])
taskEditPage.validateInput('assignee_email', dbTask.assignee['email'])
TaskEditPage.validateInput('title', dbTask.title);
TaskEditPage.validateInput('description', dbTask.description);
TaskEditPage.validateInput('state', dbTask.state);
TaskEditPage.validateInput('assignee_name', dbTask.assignee['name'])
TaskEditPage.validateInput('assignee_email', dbTask.assignee['email'])
});
it('should have updated title in overview after edit, but same task id as before', () => {
browser.get('/tasks/edit/' + dbTask.id);
const newTitle = 'Ersten Prototyp mit Angular 4.0 entwickelt';
const taskEditPage = new TaskEditPage(false);
taskEditPage.clearEnterTitle(newTitle);
let taskOverviewPage = taskEditPage.submitTaskForm();
@ -41,5 +42,12 @@ describe('Edit Task Form', function () {
taskOverviewPage.clickTask(newTitle).validateCurrentUrl('tasks/edit/' + dbTask.id);
});
it('should have return to Overview after cancel button click', () => {
browser.get('/tasks/edit/' + dbTask.id);
const taskEditPage = new TaskEditPage(false);
const taskOverviewPage = taskEditPage.cancelSubmitTask();
taskOverviewPage.verifyNewTask(newTitle);
});
});

View File

@ -6,11 +6,11 @@
"scripts": {
"ng": "ng",
"start": "concurrently \"node projects-server/server.js db=projects-server/db.json\" \"ng serve\" ",
"starte2e": "concurrently \"node projects-server/server.js db=projects-server/test.json\" \"ng serve --env=e2e\" ",
"starte2e": "cp ./projects-server/safe/test.json ./projects-server/test.json && concurrently \"node projects-server/server.js db=projects-server/test.json\" \"ng serve --env=e2e\" ",
"lint": "tslint \"src/**/*.ts\" --project src/tsconfig.json --type-check && tslint \"e2e/**/*.ts\" --project e2e/tsconfig.json --type-check",
"test": "ng test",
"pree2e": "cp ./projects-server/safe/test.json ./projects-server/test.json && webdriver-manager update --standalone false --gecko false",
"e2e": "concurrently \"node projects-server/server.js db=projects-server/test.json\" \"ng e2e --env=e2e\" ",
"pree2e": "webdriver-manager update --standalone false --gecko false",
"e2e": "cp ./projects-server/safe/test.json ./projects-server/test.json && concurrently \"node projects-server/server.js db=projects-server/test.json\" \"ng e2e --env=e2e\" ",
"install-server": "npm install --prefix ./projects-server ./projects-server",
"e2e-screenshots": "protractor ./protractor-html-reporter.conf.js",
"postinstall": "npm run install-server"

View File

@ -3,7 +3,7 @@ import {BlogEntryComponent} from "./blog-entry.component";
import {BlogEntry} from "./blog-entry";
import {BlogComponent} from "../blog.component";
import {RouterTestingModule} from "@angular/router/testing";
import {Component} from "@angular/core";
import {MockBlogComponent} from "../../mocks/mock-blog.component";
describe('Blog Entry Isolated Test', () => {
@ -52,38 +52,12 @@ describe('Blog Entry Isolated Test', () => {
const blogDelete = element.querySelector('div /deep/ .blog-delete > button').textContent;
expect(blogDelete).toBe("Entfernen")
// keine Überprüfung der id, die lediglich im EventListener des Delete Button hinterlegt ist, möglich!
// nur durch click-Event auslösen, was jedoch BlogComponent vorraussetzt
});
});
describe('BlogEntryComp -> BlogComp Dependent Test', () => {
it('should remove entry from BlogComponent on "delete" button click', () => {
TestBed.configureTestingModule({
declarations: [BlogEntryComponent, MockBlogComponent]
});
const entryFixture = TestBed.createComponent(BlogEntryComponent);
const entryInstance: BlogEntryComponent = entryFixture.componentInstance;
const blogFixture = TestBed.createComponent(MockBlogComponent);
const blogInstance: any = blogFixture.componentInstance;
const blogEntry: BlogEntry = blogInstance.entries[0];
entryInstance.entry = blogEntry;
entryInstance.blogComponent = blogInstance;
const oldLength = blogInstance.entries.length;
entryFixture.nativeElement.querySelector('div /deep/ .blog-delete > button').click();
expect(blogInstance.entries.length).toBe(oldLength - 1);
});
it('should remove entry from BlogComponent on "delete" button click : OVERRIDE BLOG TEMPLATE', () => {
TestBed.overrideComponent(BlogComponent, {
@ -103,13 +77,38 @@ describe('Blog Entry Isolated Test', () => {
const blogFixture = TestBed.createComponent(BlogComponent);
const blogInstance: BlogComponent = blogFixture.componentInstance;
const blogEntry: BlogEntry = blogInstance.entries[0];
entryInstance.entry = blogEntry;
entryInstance.entry = blogInstance.entries[0];
entryInstance.blogComponent = blogInstance;
const oldLength = blogInstance.entries.length;
entryFixture.nativeElement.querySelector('div /deep/ .blog-delete > button').click();
expect(blogInstance.entries.length).toBe(oldLength - 1);
for (let entry in blogInstance.entries) {
expect(entry).not.toBe(entryInstance.entry);
}
});
it('should remove entry from BlogComponent on "delete" button click : MOCK BLOG COMPONENT', () => {
TestBed.configureTestingModule({
declarations: [BlogEntryComponent, MockBlogComponent]
});
const entryFixture = TestBed.createComponent(BlogEntryComponent);
const entryInstance: BlogEntryComponent = entryFixture.componentInstance;
const blogFixture = TestBed.createComponent(MockBlogComponent);
const blogInstance: any = blogFixture.componentInstance;
entryInstance.entry = blogInstance.entries[0];
entryInstance.blogComponent = blogInstance;
const oldLength = blogInstance.entries.length;
entryFixture.nativeElement.querySelector('div /deep/ .blog-delete > button').click();
expect(blogInstance.entries.length).toBe(oldLength - 1);
for (let entry in blogInstance.entries) {
expect(entry).not.toBe(entryInstance.entry);
}
});
});
@ -117,20 +116,6 @@ describe('Blog Entry Isolated Test', () => {
});
// Mocked Blog Component
@Component({
selector: 'blog',
template: '<blog-entry></blog-entry>'
})
export class MockBlogComponent {
entries = [{}, {}];
deleteBlogEntry(id) {
this.entries.splice(0, 1);
}
}

View File

@ -53,6 +53,10 @@ export class BlogComponent {
this.entries.push(entry);
}
/**
* Löscht den Eintrag mit der gegebenen ID aus der Liste
* @param id - Objekt-ID des zu löschenden Eintrags
*/
deleteBlogEntry(id: number) {
let entryIndex = this.entries.findIndex(entry => entry.id === id);
if (entryIndex >= 0) {

View File

@ -3,7 +3,7 @@ import {LoginComponent} from "./login.component";
import {RouterTestingModule} from "@angular/router/testing";
import {LoginService} from "../services/login-service/login-service";
import {FormsModule} from "@angular/forms";
import {MockLoginService} from "../mocks/mock-login-service.spec";
import {MockEmptyClass} from "../mocks/mock-empty-class";
import Spy = jasmine.Spy;
@ -14,14 +14,13 @@ describe('Login Component Template Driven Form Test with Spy', () => {
imports: [FormsModule, RouterTestingModule.withRoutes([])],
declarations: [LoginComponent],
providers: [
{provide: LoginService, useClass: MockLoginService}
{provide: LoginService, useClass: MockEmptyClass}
],
})
});
it('should be possible to request login', () => {
const inputUser = 'testuser';
const inputPass = 'testpass';

View File

@ -0,0 +1,15 @@
import {Component} from "@angular/core";
@Component({
selector: 'blog',
template: '<blog-entry *ngFor="let entry of entries" [entry]="entry" [blogComponent]="this"></blog-entry>'
})
export class MockBlogComponent {
entries = [{id: 1}, {id: 2}];
deleteBlogEntry(id) {
this.entries.splice(0, 1);
}
}

View File

@ -0,0 +1,3 @@
export class MockEmptyClass {
}

View File

@ -1,3 +0,0 @@
export class MockLoginService {
}