SlideShare a Scribd company logo
1 of 37
Download to read offline
効果的なBDDテスト
Effective BDD Testing [iOS]
iOS Test Night #11
デレック・リー @derekleerock
[ GitHub・Twitter・FB・LinkedIn ]
1
自己紹介
→ Full-Stack XP/TDD/Pair Pro
Engineer @ Pivotal Labs Tokyo
→ Swift, Objective-C, JavaScript/
React, Java/Kotlin/Spring
→ Tokyo iOS Meetup Co-Facilitator
→ Aspiring Drummer/Educator
→ Weight Training, Hiking, SUP,
Ping Pong, Spikeball
→ Meditation, Essentialism (Book),
Tim Ferriss Show Podcast
2
BDDの特徴
→ テスト名は文書で書く Test names as sentences
→ 自然言語 Natural language
→ ユーザー観点 User perspective
→ 振る舞いにフォーカス Focus on behavior
3
iOSのBDD Frameworkといえば? → QUICK
describe("some object") {
context("when some condition") {
it("behaves the way I expect") {
// 準備 Arrange // GIVEN
// 実行 Act // WHEN
// 期待 Assert // THEN
}
}
}
4
iOSのBDD Frameworkといえば? → QUICK
describe("some object") {
context("when some condition") {
it("behaves the way I expect") {
// 準備 Arrange // GIVEN
// 実行 Act // WHEN
// 期待 Assert // THEN
}
}
}
4
iOSのBDD Frameworkといえば? → QUICK
describe("some object") {
context("when some condition") {
it("behaves the way I expect") {
// 準備 Arrange // GIVEN
// 実行 Act // WHEN
// 期待 Assert // THEN
}
}
}
4
iOSのBDD Frameworkといえば? → QUICK
describe("some object") {
context("when some condition") {
it("behaves the way I expect") {
// 準備 Arrange // GIVEN
// 実行 Act // WHEN
// 期待 Assert // THEN
}
}
}
4
iOSのBDD Frameworkといえば? → QUICK
describe("some object") {
context("when some condition") {
it("behaves the way I expect") {
// 準備 Arrange // GIVEN
// 実行 Act // WHEN
// 期待 Assert // THEN
}
}
}
4
"Outside-In" BDDの
ViewControllerテストの事例
テスト駆動型開発で説明する
5
テスト:実装のクラスの関数を直接呼び出す方法
describe("ログイン") {
context("ログインボタンをタップするとき") {
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
logonVC.didTapLogonButton()
expect(...)
}
}
}
6
テスト:実装のクラスの関数を直接呼び出す方法
describe("ログイン") {
context("ログインボタンをタップするとき") {
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
logonVC.didTapLogonButton()
expect(...)
}
}
}
6
テスト:実装のクラスの関数を直接呼び出す方法
describe("ログイン") {
context("ログインボタンをタップするとき") {
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
logonVC.didTapLogonButton()
expect(...)
}
}
}
6
テスト:実装のクラスの関数を直接呼び出す方法
describe("ログイン") {
context("ログインボタンをタップするとき") {
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
logonVC.didTapLogonButton()
expect(...)
}
}
}
6
コード:関数を定義しても、
UIButtonのtargetは設定していない
class LogonViewController: UIViewController {
func didTapLogonButton(sender: UIButton) {
// ...
}
}
7
テスト:ボタンをタップのふりをする方法
describe("ログイン") {
context("ログインボタンをタップするとき") {
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
logonVC.logonButton.sendActions(for: .touchUpInside)
expect(...)
}
}
}
8
コード:UIButtonのtargetを設定して、
関数をprivateに変更できるようになる
class LogonViewController: UIViewController {
let logonButton: UIButton!
init() {
super.init(nibName: nil, bundle: nil)
logonButton.addTarget(
self,
action: #selector(didTapLogonButton(sender:)),
for: .touchUpInside
)
}
↓ ↓
@objc private func didTapLogonButton(sender: UIButton) {
// ...
}
}
9
コード:UIButtonのtargetを設定して、
関数をprivateに変更できるようになる
class LogonViewController: UIViewController {
let logonButton: UIButton!
init() {
super.init(nibName: nil, bundle: nil)
logonButton.addTarget(
self,
action: #selector(didTapLogonButton(sender:)),
for: .touchUpInside
)
}
↓ ↓
@objc private func didTapLogonButton(sender: UIButton) {
// ...
}
}
9
テスト:リファクタリング
extension UIButton {
func tap() {
sendActions(for: .touchUpInside)
}
}
logonVC.logonButton.sendActions(for: .touchUpInside)
↓ ↓
logonVC.logonButton.tap()
10
テスト:リファクタリング
extension UIButton {
func tap() {
sendActions(for: .touchUpInside)
}
}
logonVC.logonButton.sendActions(for: .touchUpInside)
↓ ↓
logonVC.logonButton.tap()
10
コード:理想なのは、UIButtonもprivateにしたい
class LogonViewController: UIViewController {
↓ ↓
private let logonButton: UIButton!
...
@objc private func didTapLogonButton(sender: UIButton) {
// ...
}
}
11
テスト:リファクタリング
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
logonVC.logonButton.tap()
expect(...)
}
12
テスト:リファクタリング
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
logonVC.logonButton.tap()
expect(...)
}
12
テスト:リファクタリング
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
for subview in logonVC.view.subviews {
}
expect(...)
}
13
テスト:リファクタリング
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
for subview in logonVC.view.subviews {
if let button = subview as? UIButton {
}
}
expect(...)
}
14
テスト:リファクタリング
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
for subview in logonVC.view.subviews {
if let button = subview as? UIButton {
button.tap()
break
}
}
expect(...)
}
15
テスト:ボタンのテキストのテストを改善
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
for subview in logonVC.view.subviews {
if let button = subview as? UIButton {
if button.titleLabel?.text == "Logon" {
button.tap()
break
}
}
}
expect(...)
}
16
テスト:ボタンのテキストのテストを改善
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
for subview in logonVC.view.subviews {
if let button = subview as? UIButton {
if button.titleLabel?.text == "Logon" {
button.tap()
break
}
}
}
expect(...)
}
16
テスト:リファクタリング
it("ユーザーの認証を確認する") {
let logonVC = LogonViewController(...)
logonVC.tapButton(withText: "Logon")
expect(...)
}
17
コード:subviewに追加する
class LogonViewController: UIViewController {
private let logonButton: UIButton!
init() {
super.init(nibName: nil, bundle: nil)
logonButton.addTarget(...)
view.addSubview(logonButton)
}
...
}
18
UIButtonDecouple Repo
github.com/derekleerock/UIButtonDecouple
19
これは面白いけど、
ちょっと大変じゃない?
20
サシンクト(Succinct)を紹介!
github.com/derekleerock/Succinct
21
サシンクトのゴール ①
→ 単体テストの速さでUIもテストできるようになる
UI tests at the speed of unit tests
→ Swiftのクラスをちゃんとキャプセルカできる
Proper encapsulation
22
サシンクトのゴール ②
→ どんなアーキテクチャを使っても構わない
Architecture agnostic (MVC, MVVM, MVPなど)
→ リファクタリングの自由度が高い
Freedom to refactor
23
サシンクトの特徴
→ UIViewControllerのUIViewを回帰でViewを検索
→ テスト駆動型開発で作ったので、
テスト方法にも参考になる
→ 改善・新機能はGitHub Issueで管理している
→ OpenSource - PRs Welcome!
24
25
ご静聴ありがとうございました!
Derek Lee
@derekleerock
github.com/derekleerock/Succinct
26

More Related Content

Similar to Ss upload

Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...Shotaro Suzuki
 
RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介
RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介
RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介Fumiya Sakai
 
Entity Framework 5.0 deep dive
Entity Framework 5.0 deep diveEntity Framework 5.0 deep dive
Entity Framework 5.0 deep diveAtsushi Fukui
 
Ansible 2.0を使って組む kubernetesクラスタ vol.1
Ansible 2.0を使って組む kubernetesクラスタ vol.1Ansible 2.0を使って組む kubernetesクラスタ vol.1
Ansible 2.0を使って組む kubernetesクラスタ vol.1Hidetoshi Hirokawa
 
少しずつ手厚くして不具合や仕様漏れを防ぐために
少しずつ手厚くして不具合や仕様漏れを防ぐために少しずつ手厚くして不具合や仕様漏れを防ぐために
少しずつ手厚くして不具合や仕様漏れを防ぐためにFumiya Sakai
 
iOSアプリケーションの Unit Test
iOSアプリケーションの Unit TestiOSアプリケーションの Unit Test
iOSアプリケーションの Unit TestKatsumi Kishikawa
 
もう怖くないモバイルアプリ開発!
もう怖くないモバイルアプリ開発!もう怖くないモバイルアプリ開発!
もう怖くないモバイルアプリ開発!Toshiki Iga
 
ReduxとSwiftの組み合わせ:改訂版
ReduxとSwiftの組み合わせ:改訂版ReduxとSwiftの組み合わせ:改訂版
ReduxとSwiftの組み合わせ:改訂版Fumiya Sakai
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platformToru Yamaguchi
 
Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...Shotaro Suzuki
 
Android Lecture #01 @PRO&BSC Inc.
Android Lecture #01 @PRO&BSC Inc.Android Lecture #01 @PRO&BSC Inc.
Android Lecture #01 @PRO&BSC Inc.Yuki Higuchi
 
エンタープライズIT環境での OpenID Connect / SCIM の具体的実装方法 idit2014
エンタープライズIT環境での OpenID Connect / SCIM の具体的実装方法 idit2014エンタープライズIT環境での OpenID Connect / SCIM の具体的実装方法 idit2014
エンタープライズIT環境での OpenID Connect / SCIM の具体的実装方法 idit2014Takashi Yahata
 
ボット開発でも DevOps! BotBuilder のテスト手法
ボット開発でも DevOps! BotBuilder のテスト手法ボット開発でも DevOps! BotBuilder のテスト手法
ボット開発でも DevOps! BotBuilder のテスト手法Kenichiro Nakamura
 
初めての Data api
初めての Data api初めての Data api
初めての Data apiYuji Takayama
 
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...Yoshifumi Kawai
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejsTakayoshi Tanaka
 
cocos2d-xにおけるBox2Dの利用方法および便利なツール
cocos2d-xにおけるBox2Dの利用方法および便利なツールcocos2d-xにおけるBox2Dの利用方法および便利なツール
cocos2d-xにおけるBox2Dの利用方法および便利なツールTomoaki Shimizu
 
Tech talk salesforce mobile sdk
Tech talk   salesforce mobile sdkTech talk   salesforce mobile sdk
Tech talk salesforce mobile sdkKazuki Nakajima
 

Similar to Ss upload (20)

Mongodb
MongodbMongodb
Mongodb
 
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
 
RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介
RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介
RxDataSourceをNSDiffableDataSourceへ置き換える際のTips集紹介
 
Entity Framework 5.0 deep dive
Entity Framework 5.0 deep diveEntity Framework 5.0 deep dive
Entity Framework 5.0 deep dive
 
Ansible 2.0を使って組む kubernetesクラスタ vol.1
Ansible 2.0を使って組む kubernetesクラスタ vol.1Ansible 2.0を使って組む kubernetesクラスタ vol.1
Ansible 2.0を使って組む kubernetesクラスタ vol.1
 
少しずつ手厚くして不具合や仕様漏れを防ぐために
少しずつ手厚くして不具合や仕様漏れを防ぐために少しずつ手厚くして不具合や仕様漏れを防ぐために
少しずつ手厚くして不具合や仕様漏れを防ぐために
 
iOSアプリケーションの Unit Test
iOSアプリケーションの Unit TestiOSアプリケーションの Unit Test
iOSアプリケーションの Unit Test
 
もう怖くないモバイルアプリ開発!
もう怖くないモバイルアプリ開発!もう怖くないモバイルアプリ開発!
もう怖くないモバイルアプリ開発!
 
ReduxとSwiftの組み合わせ:改訂版
ReduxとSwiftの組み合わせ:改訂版ReduxとSwiftの組み合わせ:改訂版
ReduxとSwiftの組み合わせ:改訂版
 
Driverについて
DriverについてDriverについて
Driverについて
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platform
 
Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...
 
Android Lecture #01 @PRO&BSC Inc.
Android Lecture #01 @PRO&BSC Inc.Android Lecture #01 @PRO&BSC Inc.
Android Lecture #01 @PRO&BSC Inc.
 
エンタープライズIT環境での OpenID Connect / SCIM の具体的実装方法 idit2014
エンタープライズIT環境での OpenID Connect / SCIM の具体的実装方法 idit2014エンタープライズIT環境での OpenID Connect / SCIM の具体的実装方法 idit2014
エンタープライズIT環境での OpenID Connect / SCIM の具体的実装方法 idit2014
 
ボット開発でも DevOps! BotBuilder のテスト手法
ボット開発でも DevOps! BotBuilder のテスト手法ボット開発でも DevOps! BotBuilder のテスト手法
ボット開発でも DevOps! BotBuilder のテスト手法
 
初めての Data api
初めての Data api初めての Data api
初めての Data api
 
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs
 
cocos2d-xにおけるBox2Dの利用方法および便利なツール
cocos2d-xにおけるBox2Dの利用方法および便利なツールcocos2d-xにおけるBox2Dの利用方法および便利なツール
cocos2d-xにおけるBox2Dの利用方法および便利なツール
 
Tech talk salesforce mobile sdk
Tech talk   salesforce mobile sdkTech talk   salesforce mobile sdk
Tech talk salesforce mobile sdk
 

More from Cody Caster

More from Cody Caster (8)

Upload
UploadUpload
Upload
 
Presentation
PresentationPresentation
Presentation
 
Test link3
Test link3Test link3
Test link3
 
Test link
Test linkTest link
Test link
 
Presentation2
Presentation2Presentation2
Presentation2
 
Presentation1
Presentation1Presentation1
Presentation1
 
Test
TestTest
Test
 
Test
TestTest
Test
 

Ss upload