小编Spi*_*iff的帖子

自动验收测试 - UI或API?

我在过去几天一直在研究自动验收测试,了解BDD&JBehave,FitNesse&Slim,Selenium和WebDriver等.

我刚刚看到这个,他演示了如何使用FitNesse的编写和维护这样的测试视频由罗伯特C.马丁.接近尾声时,有人问这些测试是否会触及用户界面.Martin接着解释说,对UI的耦合验收测试成本很高,因为对UI的更改非常频繁.我还可以猜测,这些测试只能在UI开发之后编写,这将使测试人员按照定义落后于计划.

我不得不问:替代方案是什么?Martin似乎暗示测试应该是一个隐藏的层,它会操纵应用程序的业务层.我的理解是,这需要额外的工作,更不用说它会暴露一个新的API,需要在生产环境中保护一次.

可以通过应用程序服务访问业务层就足够了吗?

你有什么经验吗?

感谢分享!

automated-tests qa continuous-deployment

14
推荐指数
2
解决办法
5364
查看次数

GitVersion 性能缓慢

我们的 CI 构建的 GitVersion 步骤现在需要 4-5 分钟,我们无法真正弄清楚原因。以下是一些基本日志:

2018-09-25T14:31:02.4222252Z ##[section]Starting: GitVersion
2018-09-25T14:31:02.4227925Z ==============================================================================
2018-09-25T14:31:02.4228168Z Task         : GitVersion Task
2018-09-25T14:31:02.4228396Z Description  : Easy Semantic Versioning (http://semver.org) for projects using Git
2018-09-25T14:31:02.4228654Z Version      : 3.6.5
2018-09-25T14:31:02.4229010Z Author       : GitVersion Contributors
2018-09-25T14:31:02.4229302Z Help         : See the [documentation](http://gitversion.readthedocs.org/en/latest/) for help
2018-09-25T14:31:02.4229565Z ==============================================================================
2018-09-25T14:31:02.4366228Z Preparing task execution handler.
2018-09-25T14:31:02.6709097Z Executing the powershell script: d:\w\_tasks\GitVersion_e5983830-3f75-11e5-82ed-81492570a08e\3.6.5\GitVersion.ps1
2018-09-25T14:31:03.0124372Z Current Directory:  D:\w\_tasks\GitVersion_e5983830-3f75-11e5-82ed-81492570a08e\3.6.5
2018-09-25T14:31:03.0124924Z 
2018-09-25T14:31:03.0125184Z 
2018-09-25T14:31:03.0130879Z Sources Directory:  d:\w\1\s
2018-09-25T14:31:03.0131239Z 
2018-09-25T14:31:03.0131454Z 
2018-09-25T14:31:03.0230450Z Invoking GitVersion with d:\w\1\s /output buildserver /nofetch
2018-09-25T14:31:03.0231023Z 
2018-09-25T14:31:03.0231265Z …
Run Code Online (Sandbox Code Playgroud)

gitversion

7
推荐指数
1
解决办法
1503
查看次数

交易和发送电子邮件

考虑用户在Web应用程序上创建新帐户的常见用例,以及应用程序向用户的地址发送确认电子邮件.从我所看到的,这通常以3种方式之一实现:

  1. Web控制器调用服务方法,该方法在单个事务中创建用户帐户并发送电子邮件.
  2. Web控制器调用服务方法(使用tx propagation = never),它调用自身的第一个方法在事务中创建用户帐户,然后调用第二个方法来发送电子邮件.
  3. Web控制器调用第一个服务方法,该方法在事务中创建用户帐户,然后调用第二个发送电子邮件的服务方法.

第一种方法简单明了,但存在发送电子邮件后回滚事务的风险,从而使电子邮件无效.第二种方法更复杂,但它保证只有在用户创建实际成功时才发送电子邮件.第三种方法很简单,但是使用不应该知道的业务逻辑来加重Web层.

是不是有一种更简单的方法,也许是AOP驱动的,可以保证只有在用户创建事务实际成功时才会发送电子邮件?我是否认为第一种方法可能会失败?

我们正在使用Java EE + Spring堆栈并且愿意集成其他API(AOP?Spring Integration?)来实现这一目标.

干杯!

java email spring transactions

5
推荐指数
2
解决办法
5332
查看次数

角度-模板中的错误导致无限循环

请考虑以下代码:

//our root app component
import {ChangeDetectionStrategy, Component, ErrorHandler, Injector, NgModule, ViewContainerRef} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
import {ToastModule, ToastsManager} from "ng2-toastr/ng2-toastr";

@Component({
  selector: 'my-app',
  template: `
    <div>
      name={{(test$|async).name}}
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class App {
  test$: Observable<{name:string}> = null;

  constructor(toastr: ToastsManager, viewContainerRef: ViewContainerRef) {
    toastr.setRootViewContainerRef(viewContainerRef);
  }
}

export class CustomErrorHandler extends ErrorHandler {
  constructor(private injector: Injector) { super(); }
  handleError(err: any): void {
    super.handleError(err);
    this.injector.get(ToastsManager).error(err.message);
  }
}

@NgModule({
  imports: [ BrowserModule, BrowserAnimationsModule, …
Run Code Online (Sandbox Code Playgroud)

angular

5
推荐指数
1
解决办法
378
查看次数

在通过ViewContainerRef创建的OnPush组件更改后,角度视图未更新

使用Angular 4.3和以下的Plunkr.

请考虑以下组件:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <button type="button" (click)="toggle()">Toggle</button>
      <div #anchor></div>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class App {
  @ViewChild('anchor', {read: ViewContainerRef}) anchor: ViewContainerRef;
  dynamicRef: ComponentRef;
  value = true;

  constructor(private cfr: ComponentFactoryResolver, private cdr: ChangeDetectorRef) {}

  ngAfterViewInit(): void {
    let factory = this.cfr.resolveComponentFactory(Dynamic);
    this.dynamicRef = this.anchor.createComponent(factory);
    this.dynamicRef.instance.value = this.value;
    this.dynamicRef.changeDetectorRef.detectChanges();
  }

  toggle(): void {
    this.value = !this.value;
    this.dynamicRef.instance.value = this.value;
    this.dynamicRef.changeDetectorRef.detectChanges();
  }
}

@Component({
  template: `Value: {{value}}`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class Dynamic { …
Run Code Online (Sandbox Code Playgroud)

angular

2
推荐指数
1
解决办法
963
查看次数