My Favorite Things - Coding or die.

とある技術者の経験記録、的な。

エンジニア仲間とブログを開設しました。 - ペンギン村 Tech Blog

1年半くらい前になるでしょうか、ペンギン村というSlackを作ってエンジニア仲間と情報交換をしていました。

人数も少しずつ増えてきて、なんか面白いことをやりたいね、ということで新たにブログを開設しました。
blog.penginmura.tech

とりあえず、最初の挨拶的な記事と、前から書きたいと思っていたKotlinの記事を書いてみました。
blog.penginmura.tech
blog.penginmura.tech

やはり一緒に何かに対して取り組むというのは、個人的に非常に楽しく感じると思う今日この頃です。

そのうち何かサービスを作っていきたい的な話もあるので、今からどうなるか楽しみにしています。

まぁ、こういったものは最初だけ気合が入ったものの途中から興味を失うということもあるので、この先どうなるかは分かりませんが。

といった感じで、新年最初のブログ記事でした。(久しぶりに本当にただのブログという感じ)

JJUG CCC 2017 Fall に参加してきた(いまさらまとめ)

さて、JJUG CCC 2017 Fallに参加してきました。

f:id:yu_dotnet2004:20171226223647p:plain

はい、2017/11/18に開催されたもので、すでに参加から1ヶ月以上が経っています。しかし、年内にやり残していたこととして記憶していたので軽くまとめたいと思います。

今回はKotlinの話を聞きたいと思ったのがキッカケで、Springなどの話も面白そうだと思ったので参加を決めました。懇親会も参加する予定だったのですが、体調を崩してしまって参加できなかったのは少し残念です。

ところでCCCって何の略かと思ったら「Cross Community Conference」の略みたいですね。なんだかカッコいいです。

10年前のレガシーシステムをサーバサイドKotlinでフルリニューアルした話

speakerdeck.com

  • 自己紹介
  • API部分をやった
    • Kotlin x SpringBoot x (Vue.js)
  • エンジニア3人で
  • どうやって経営層を通したか?
    • 最優先のIssueを見極めた
    • 可能な限り数値化
    • 複数案(メリット・デメリット)
      • 自分でも客観的に見られるようになる
  • プロトタイプで不確実性をコントロール
    • 自分でも自身がつく
    • 説得力につながる
  • 技術選定
    • API
      • 重複ロジック・DBの一元化
      • 型をしっかりしたい
    • DBアクセス
      • DOMA2
        • SQL外出できる
      • ElasticSearch
  • なぜKotlin?
  • 技術スタック
    • Rails 5.1
      • Vue.jsやAngularの開発が楽
    • Vue.js
    • Element
      • Vue.jsのフレームワーク
      • 管理画面に最適(Bootstrapみたいな印象)
      • スター数も多い
    • Kotlinの学習コストは問題にならなかった
      • SprintBootの学習コストのほうが
    • API部分はSwaggerで生成して、Railsから叩く
  • Spring
    • SPRING INITIALIZERを使うと楽
    • アノテーションなど問題なし
    • kotlin-springプラグイン
      • デフォルトでopenになってくれる(継承可)
    • jackson-module-kotlin
  • DOMA2
    • 公式サポートはされていなかった
    • Doma層はJavaで書くという選択をした
  • swagger-codegen
    • SpringFox
      • 定義ファイルを生成してくれる
  • どこでもKotlin
    • 勉強会的な
  • 他社事例
    • Retty
    • CA

上層部に提案する際の進め方として「複数案を用意する」「実際に動くプロトタイプを作る」というのはやはり重要だと思いました。

JavaとKotlinの共存という面では、変化の少ないDBアクセス層部分はJavaで書くという選択は素晴らしいと思いました。あと、kotlin-springプラグインを利用することで、デフォルトでopenにしてくれるという話を聞き、Kotlinにはそんな機能もあるのだと思いました。

swagger-codegenは使ったことが無いのですが、いろいろな勉強会でよく聞きますし、個人開発で使ってみたいと思いました。(こういうのって最初に始めるところが壁があるのですよね・・・便利だとは分かっていても)

ちなみにベルセルクは読んだことがないのですが、ちょっと興味がわきました。

Pivotal認定講師が徹底解説! Spring Bootの本当の理解ポイント

www.slideshare.net

  • SpringBoot
    • まずはSpringを理解せよ
  • Spring
    • CoCではない
      • 設定ファイルはJavaコードで記述する
      • 開発を始めるのが面倒
      • Spring Bootは設定の塊
      • 設定=Bean定義
    • DIコンテナ
      • 1つ目
        • ただの「Bean」と呼ぶ
        • Bean定義=このクラスのインスタンスをBeanとしてね
        • コンポーネントスキャン(Configurationクラス)
          • どこからコンポーネントを探してくるか
          • パッケージを指定(サブパッケージも探してくれる)
        • コンテナ初期化時にConfigurationクラスを指定する
        • @Autowired
          • コンストラクタが単一だったら省略可
          • なのであんまり使わない
      • 2つめ
        • @Bean
          • 他のBeanを引数で受け取れる
      • @Componentと@Beanは併用できる
    • Spring MVC
      • DispatcherServlet
        • 唯一のサーブレット
        • ルーティングして、別のコントローラを呼び出す
        • コントローラからViewの論理名を返す
        • ViewResolverでビューの物理名を取得
        • これがコンテナを持ってる
      • 特徴
        • カスタマイズしやすい
        • コンポーネントがインターフェース化されてる
          • 実装クラスはコンテナから取得される
      • ViewResolver
      • @EnableWebMvc
        • @Beanで毎回定義するのは面倒くさい、ので導入された仕組み
        • @Import
        • Java Configを合体させるアノテーション
      • @Controller
  • Spring Boot
    • Beanの種類
      • FWが利用するもの
      • アプリケーションロジック(自分たちで書くもの)
    • Spring Bootがやっていること
      • FWが利用するBeanを事前に定義しておくだけ
      • JavaConfigのかたまり
        • AutoConfigurationクラスが大量にある
      • アプリケーションロジックのBeanには何もない
      • Springの知識が必須
      • Springをかんたんに使えるようにしたのがSpringBoot
    • application.properties
      • FWのBeanの各設定値
    • @ConfigurationProperties
      • application.propertiesの設定値をBeanに反映するもの
    • 起動するプロセス
    • 定義するBeanの選別
      • spring-boot-autoconfigure.jar
        • すべてのBeanが定義されている
      • 無駄なBeanをコンテナに登録しないようにする仕組みがある
        • @ConditionalOnXxx
          • 条件に合致した場合にそのBeanが定義される
  • カスタマイズ方法(トラブル回避)
    • @ConditionalOnXxx による芋づる式のトラブル
    • @EnableXxxをあまり使わないほうが良い
      • Spring Cloudとかでは使う必要もある
    • 安全な方法
      • application.properties
      • BeanをDIで取得して設定変更(コンストラクタInjection)
    • 補助的なBeanを定義する
      • ThymeleafなどのBeanに拡張の仕組みが用意されている
      • Dialectという形で用意
  • Springの本
    • Beanの丸写しはしないように(SpringBootの場合)

私は以前Seasar2を用いた開発を行ったことがあり、SpringもDIコンテナなんだなくらいにしか知らなかったのですが、この発表を聞いてSpringBootとSpringの関係がようやく理解できたような気がします。

SpringがCoCでなく設定を大量に記述する必要があること、そしてその負担を軽減するための設定ファイルの塊を生成してくれるのがSpringBootであるという理解で落ち着きました。

普段はSpringを使う機会がないのですが、今度Kotlinで触ってみようかと思っているので、その際にこの資料を見ながらSpringの基礎を固めたいなと思いました。

Spring Security にできること・できないこと

qiita.com

  • どこが守られるのか、どこが守られないのか
  • 使った実装 vs 使ってない実装
  • Servletのフィルターを利用した実装
  • セッション管理の不備(セッションID)
    • 推測
      • 連番とか
      • 推測できないランダム値を生成する
      • Servletの話になるので管轄外
    • 盗用
      • セッションIDをクエリパラメータに載せる
        • リファラーに載ってしまう
        • 対策:cookieにのせる
        • ServletではCookieをサポートしてないClientもサポートする仕様
        • SpringSecurity
          • URLリライティングが行われていた場合に止める
      • http通信でcookieを載せる
        • Cookieはヘッダに載るので、暗号化していないとNG
        • secure属性をつけることで、http通信では送信されなくなる
        • これもServletの話なので、SpringSecurity関係ない
    • セッションIDの固定化
      • ログイン前後でセッションIDが変更されていない場合に起こる
      • セッションIDを対象者にセットしておくことで、そのセッションIDでログインできる
      • 対策:ログインしたらセッションIDを変える
        • Spring SecurityはFormログインしていれば、自動的にやってくれる
  • XSS
  • CSRF
    • 関係ないサイトからのリクエストが正規のユーザとして処理される問題
    • 意図しない投稿をSNSにしたり
    • 対策:
      • 2つのリクエストを区別する必要がある
      • セッションIDとは別にトークンを発行して、それをリクエストに載せるようにする
        • それが乗っていれば正規のリクエス
      • Spring Securityは自動でやってくれる
        • GET, HEAD, TRACE, OPTIONS 以外がチェックされる
          • これらはHTTPの仕様上、読み取り専用の操作なので
  • HTTP ヘッダーインジェクション
    • ユーザの入力値をレスポンスヘッダに利用する場合
    • HTTPヘッダにおいて改行は意味をもつので、任意のヘッダを偽装可能
    • 空行を入れれば、bodyも改ざんできてしまう
    • 対策:
      • Servletなどが用意しているAPIを利用すべき
      • Servletの仕様としては定められていない
      • Spring Securityでは、改行コードがあった場合にエラーとなる
        • IllegalArgumentException(500)
  • Clickジャッキング
    • 見えないiframeを表示する
    • 対策:
      • X-Frame-Options
      • 主要なブラウザはサポートしている
      • Spring Security もサポート
  • 権限
    • ルーティングごとの適切なアクセス制御を設定する

Webセキュリティの復習になったような気がします。

そしてSpring Securityというものも初めて聞いて、Springは随分と巨大なFW群になったのだと感じました。ServletのFilter機能を利用している、なのでHTTPリクエスト前後で出来ることしか行えない、ということが重要であると思いました。

発表はデモを多く使用されていたので、普段イメージしにくい攻撃が理解しやすくてとても良かったです。

オレオレJVM言語を作ってみる(四則演算するだけだけど)

www.slideshare.net

  • 構成
  • ANTLR
    • アントラー
    • パーサジェネレータ
    • 文法を渡すことでコードが生成される
    • EBNF
      • :の左側が名前
      • のコメントがJavaのクラス名

    • antlr4 Math.g4
      • ANTLRのJARにあるクラスを実行してるだけ
    • javac -cp antlr-.jar Math.*
    • grun Math prog -guiコマンドでテストできる
    • Truffleで処理するために変換する必要がある
      • ツリーの変換処理が必要になる
    • tree walk
      • 深さ優先で探索していく処理
      • リスナーを実装する
  • Truffle(トラフル)
  • Eclipse OMR
  • Graal & Truffle
    • Graalは具体的な言語実装を知らない

ハッキリ言ってとても難しかったです・・・。

なんとなくぼんやりと全体のイメージが出来たような気がしますが、それも怪しいです。

新しいプログラミング言語の学び方 ~ HTTPサーバーを作って学ぶJava, Scala, Clojure ~

speakerdeck.com

  • 新しい言語を学ぶときはHTTPサーバを作ると良いよ、という話
  • なぜ?
    • よくあるやり方
      • HelloWorld、書籍、TODOアプリ
    • WebでTODOアプリ
      • DBが必要になり
      • MySQLWorkBench
      • 画面表示は?
    • HTTPサーバなら必要ない
  • HTTPサーバのやってること
    • リクエストの待受
    • パース
    • 結果を返す
  • Scala
    • 省略可能な構文
    • 強力な標準ライブラリ
    • 新しい制御構文も作れる
    • オブジェクト指向+関数型の強さ
      • マーチンオダスキーさんが言ってる
      • case class
        • oopでは値オブジェクト
        • 関数型では代数的データ型
  • Clojure
  • 作り始めるコツ
    • 難しく考えなくても良いかも
    • n年後にもう一度作り直すと成長を実感できる
  • HTTP
    • Socket=(IP+ポート)
    • 流れ
      • ServerSocketの初期化
      • while
      • accept
      • input/output stream を取得
      • inputからread、outputにwrite
  • 正規表現
    • リクエストラインの抽出
    • Java7から正規表現に名前付きグループが使えるようになった
    • Scala
      • パターンマッチ("".r
    • Clojure
      • re-find #"xxxx"
      • restHaskellでいうところのtail
      • zipmap
        • method, path, version をキーにして入る
    • Javaでは名前付きグループ
    • Scalaではパターンマッチ
    • Clojureではre-find+強力なコレクションライブラリ
  • リソースの開放
    • Java
      • try-with-resource
    • Scala
      • Loan Pattern
      • 「借りたら返す」を確実に行う
      • DSLとして提供してる(メソッド)
      • 関数の引数が1つの場合は、{}で関数を渡せる
    • Clojure
      • with-open
  • 並行処理
  • 文字列連結
    • Java
      • StringBUilder
        • javap -cで分析
    • Scala
      • String Interporation
      • Multi String Literarl
    • Clojure
      • str
      • s式が好きになってくる
  • まとめ
    • すでに知っているものとdiffを取ってみる

話の流れがスムーズで分かりやすく、聞いていて面白いセッションでした。

私も新しい言語を学ぶ時に、最近だとConsListは書くようにしているのですが、どうも物足りなく感じていたのでHTTPサーバを作ってみようかなとこのセッションを聞いて思いました。

Clojureは以前Lisp系の言語を学ぼうと思って2日間くらい勉強したのですが、それきりだったので今度また勉強してみようと思いました。

作り始める際に最初からがんばりすぎない(その言語の機能をフルに活用しようとしない)というのは、モチベーションというかやり方として大切だなと思いました。

感想

JJUGは初参加だったのですが、かなりの人数が参加されていてとても驚きました。

それゆえ、満員で参加できないセッションもあったのが残念ですが、まぁそれは仕方がないでしょう。

有益な発表がいろいろ聞けて、発表者および運営者の方には大変感謝です。 f:id:yu_dotnet2004:20171226223740p:plain

Quick/Nimbleで独自Matcherを自作して、テストコードの可読性を上げる

さて今年も終わりに近づいてきました。

この記事はモバイル 自動化 / 自動テスト Advent Calendar 2017の17日目の記事です。

実はアドベントカレンダーの参加は今回が初めてだったりするのですが、まぁそれはどうでも良いですよね。

Tl;Dr

Quick/Nimbleで、独自Macherを作成するとテストコードの可読性が上がるかも?

// 標準のMatcherを使用
it("use built-in matcher") {
    expect(person1.isTeen()).to(beTrue())
    expect(person2.isTeen()).to(beFalse())
    expect(person1.gender).to(equal(person2.gender))
    expect(person1.gender).toNot(equal(person3.gender))
}

// 独自のMatcherを使用
it("use custom matcher") {
    expect(person2).to(teen())
    expect(person1).toNot(teen())
    expect(person1).to(sameGender(person2))
    expect(person1).toNot(sameGender(person3))
}

iOS Test Night

さて、iOS Test Night #6 - 1周年 - では、Quick/Nimbleのイケてないところを改善したい、といった内容で発表をさせていただきました。 speakerdeck.com

その中で「Matcher APIはコード補完が効きづらいのがイケてない」的な話をしました。

たしかにMatcher APIはコード補完が効きづらく、初心者にとっては学習コストが高いものです。しかし、Matcher APIが悪いかというとそうではなく、あえて柔軟に作られるように設計されています。

そこで今回は、独自のMatcherを作成する方法と、それによってテストコードがどのように変わるのか見ていきたいと思います。

Quick?

QuickはSwift製のBDDフレームワーク(+Matcher APIベースのAssertionライブラリ)です。

私の記憶では、Swiftがリリースされてから2日後くらいには公開されていた、かなり早くからあるテスティングフレームワークです。Ruby製のBDDフレームワークであるRSpecなどにインスパイアされていると、公式のREADMEで書かれています。

BDDフレームワークとは「振る舞い(Behavior)」に着目してテストコードを書こうという思想のテスティングフレームワークです。

歴史的には、先にTDDによる「テスト駆動」という「テストを先に書く」という思想を開発にもたらされました。

しかし、「テストを書くこと」が目的になるという悪い側面もあり、それを解決するために(テスト対象の)「振る舞い」に着目することで質の良いテストを書こう、ということでBDDが生まれたとかどうとか。(そんな話を聞いた覚えがあるような、くらいなので間違っているかも)

以下のようにテストコードが(DSLによって)構造化されるのが最大の特徴になっています。

class SampleTest: QuickSpec {
    override func spec() {
        describe("足し算") {
            context("1 + 1") {
                it("2") {
                    expect(1 + 1).to(equal(2))
                }
            }
            context("1 + 2") {
                it("3") {
                    expect(1 + 2).to(equal(3))
                }
            }
        }
    }
}

よくありがちな単純な例ですが、テストが構造化されるのが見て取れるかと思います。

コード中に出てくる単語は、以下のような意味を持っています。

  • describe:テストの概要説明
  • context:テストの条件
  • it:期待される振る舞い

このような形で、テストコード全体が構造化されるのがBDDフレームワークの特徴になっており、さまざまな言語でBDDフレームワークが作成されていますが、この見た目に関してはだいたい似たような感じになっています。

Nimble?

Quick/Nimbleとセットで呼ばれる事が多く、実際セットで使われることが多いため、あまり意識されることは多くない(ように思える)のですが、Nimbleは「Assertionライブラリー」という位置付けになっています。

QuickがBDDフレームワークとしてDSLを提供するのに対し、NimbleはXCTestでいうところのXCTAssertEqualのような期待値と結果を比較して、テストの成否を判定する機能を提供しています。

さきほどのコード中にexpect(1 + 1).to(equal(2))といったコードがありましたが、この部分はQuickではなくNimbleに用意されたAPIを利用しています。テストコードが自然な英文になるようなAPIが提供されており、「Matcher API」と呼ばれることが多いです。

Matcher APIのメリットは、テストコードが自然な英文になることで意図が分かりやすくなることと、失敗時のエラーメッセージが分かりやすいという点が挙げられます。

expect(1 + 1).to(equal(3))
// => expected to equal <3>, got <2>

この失敗時のエラーメッセージが分かりやすいというのは意外と重要で、プロダクトコードに何らかの変更を加えた時に既存のテストが失敗した場合は、その原因をできるだけ早く知りたいと思うはずです。失敗時のエラーメッセージが不親切だと、なぜテストが失敗したかの原因を調べるのに多大な時間を消費してしまいます。

これはミクロな視点で見た時は大した問題にならないように見えますが、マクロな視点で見ると結構重要だったりします。

CI(継続的インテグレーション)により自動テストが失敗した場合に、その原因がすぐに分からない場合は(他の作業との兼ね合いで)修正が後回しにされることが多いように感じます。それが繰り返されると、テストコードのメンテナンスがされなくなり、最後には捨てられるということも少なくありません。(実際に、私も以前関わったPJで目の当たりにしています)

Matcher APIの欠点

Matcher APIは以下を提供することで、前述したような問題への対処を試みています。

  • テストコードの意図を明確にする
  • テストが失敗したときの原因を明確にする

一方で、IDEによるコード補完との相性は悪く、初心者にとっては学習コストが高めです。

その対処として、

といった改善策を考えた、というのが冒頭のiOS Test Nightでの発表内容になります。(詳しくはスライドをご参照ください)

独自Matcherを自作する

ようやくタイトル回収までたどり着きました。

Matcher APIの他のメリットとして、独自のMatcherを作成することが出来るという点が挙げられます。つまり、Built-inのAPIで十分な可読性が得られなければ、自分で拡張することもできるという意味です。

今回は以下のPerson構造体に対して、「ティーンエイジャー(13〜19歳の間)であること」と「性別が同じであること」というMatcherを作成してみたいと思います。

struct Person {
    
    enum Gender {
        case male
        case female
    }
    
    let age: Int
    let gender: Gender
    
    func isTeen() -> Bool {
        return 13...19 ~= age
    }
}

期待値を受け取らないMatcher - teen()

まずは「ティーンエイジャー(13〜19歳の間)であること」を確認するテストコードについてです。

標準のMatcherを利用したテストコードを見てみます。

let person1 = Person(age: 17, gender: .male)
let person2 = Person(age: 20, gender: .male)

describe("Person") {
    
    describe("is teen?") {

        it("use built-in matcher") {
            expect(person1.isTeen()).to(beTrue())
            expect(person2.isTeen()).to(beFalse())
        }
    }
}

悪くありませんが、isTeen()の呼び出し結果がtrue/falseであること、といった感じで少しだけ回りくどいテストコードのようにも見えます。

次に自作したteen()というMacherを利用したコードを見てみます。

let person1 = Person(age: 17, gender: .male)
let person2 = Person(age: 20, gender: .male)

describe("Person") {
    
    describe("is teen?") {

        it("use custom matcher") {
            expect(person1).to(teen())
            expect(person2).toNot(teen())
        }

    }
}

さきほどの標準APIに比べて、意図が分かりやすくなったのではないでしょうか?

以下がMatcherの実装です。

func teen() -> Predicate<Person> {
    return Predicate { (actualExpression: Expression<Person>) throws -> PredicateResult in
        let message = ExpectationMessage.expectedTo("teenager")
        if let actualValue = try actualExpression.evaluate() {
            return PredicateResult(
                bool: actualValue.isTeen(),
                message: message
            )
        } else {
            return PredicateResult(
                status: .fail,
                message: message
            )
        }
    }
}

ゴチャゴチャしているように見えますが、だいたい決まりきったコードパターンになっているので、公式のREADMEに書かれたサンプルコードを真似すればわりと簡単に作成できます。(実際、内部的な実装までは把握していません)

beTrue()のように期待値を受け取らないパターンは、このような感じのコードで実装することが出来ます。

期待値を受け取るMatcher - ()

次に「性別が同じであること」を確認するテストコードについてです。

同じように標準APIのコードを見てみます。

let person1 = Person(age: 17, gender: .male)
let person2 = Person(age: 20, gender: .male)
let person3 = Person(age: 15, gender: .female)

describe("same gender") {
    
    it("use built-in matcher") {
        expect(person1.gender).to(equal(person2.gender))
        expect(person1.gender).toNot(equal(person3.gender))
    }
}

やはり悪くはありませんが、視覚ノイズが多く、パット見で意図を読み取るのが難しくなっている印象を受けます。

次に自作したsameGender()によるテストコードです。

let person1 = Person(age: 17, gender: .male)
let person2 = Person(age: 20, gender: .male)
let person3 = Person(age: 15, gender: .female)

describe("same gender") {
    
    it("use custom matcher") {
        expect(person1).to(sameGender(person2))
        expect(person1).toNot(sameGender(person3))
    }
}

先程の標準APIに比べ、はるかにテストの意図が分かりやすくなったのではないでしょうか?

sameGender()の実装は以下のとおりです。

func sameGender(_ expectedValue: Person) -> Predicate<Person> {
    return Predicate { (actualExpression: Expression<Person>) throws -> PredicateResult in
        let message = ExpectationMessage.expectedActualValueTo("same gender <\(expectedValue)>")
        if let actualValue = try actualExpression.evaluate() {
            return PredicateResult(
                bool: actualValue.gender == expectedValue.gender,
                message: message
            )
        } else {
            return PredicateResult(
                status: PredicateStatus.fail,
                message: message
            )
        }
    }
}

引数として期待結果expectedValueを受け取るようにしているという違いはありますが、基本的には先程と同じようなコードになっています。

いつMatcherを作成すべきか?

これについて明確な答えはありません、おそらくプロジェクトによってマチマチかと思います。

独自Matcherを作成したほうが読みやすくなるからと言って、片っ端から独自Matcherを作成していたのでは、そちらのコードの記述量が多くなってしまって逆にコストが掛かるでしょう。

それにテストが失敗した時に、独自Matcherの不具合ではないかと疑いをかけたくなるケースもあるでしょう。そういう意味では独自Matcherもきちんとテストされるべきかもしれません。

しかしアプリケーションの中心となるドメインモデルがあり、独自Matcherを作成することでテストコードの可読性があげられるのであれば、独自Matcherを作成することを検討する価値はあるでしょう。

テストコードを負債にしないために

最近わたし自身が感じているのは、テストコードが失敗したときの原因が「ほぼ一瞬」で分からない場合、「面倒だからあとで調べよう」となるという気持ちのコンテキストスイッチの切り替えが心の中で起きるということです。

それは「実際に調べてみたら大した事がなかった」としても、「対応までの時間と(心理的な面も含めて)コストが掛かる」ということです。テストコードが負債になっていくのは、失敗したテストコードに対するチームメンバーの心理的ストレスではないかと思うわけです。

そういう意味で独自Matcherの作成は、適材適所で利用すれば価値があるのでは、と思ったりします。

終わり

最初は独自Matcherの作成という技術的な記事にするつもりだったのですが、なんだか途中からポエミーな感じになってしまいました。まぁ、年の瀬ですし、たまにはこういうのも良いでしょうか。

個人的に次の課題として、NimbleのMatcher APIまわりの実装の仕組みをきちんと理解したいと思うので、今度コードリーディングしてみたいなと思ったりします。

そんなわけでモバイル 自動化 / 自動テスト Advent Calendar 2017の17日目の記事でした。

皆様良いお年を。(ちょっと早い?)

勉強会:Bonfire iOS #3 に参加してきた。

さて、気づけばどうやら久しぶりのブログ更新のようです。

今回は、Bonfire iOS #3 というヤフーが開催しているIOS系の勉強会に参加してきました。 yj-meetup.connpass.com

第3回の今回のテーマは「品質」ということで、様々な会社・プロダクトに携わっている方たちが品質について発表してくださいました。

iOSの勉強会というと、開発Tipsやテストといった技術的なテーマが多い中、面白いテーマだなぁと思いました。

いつものように箇条書きメモ+感想みたいな感じで順番に書いていきたいと思います。 スライドがアップされたら更新していきたいと思います。

Yahoo!天気アプリを少人数でも支えられた理由

  • 自己紹介
    • iOS歴3年
    • Swift
    • 大阪から
  • Y天気アプリ
    • 利用者あわせて600万
    • 天候があれると1000万
    • 統合ランキングでも1位をなんども
  • 体制
    • 17人くらい
    • iOS/Android、1名ずつ
    • 他の社内サービスでも珍しい
  • 企画
    • メンバーと新機能を決める
    • PMもエンジニア経験ある
      • 企画が実装も踏まえて話を進めてくれる
    • Sckethでエンジニアがプロと
    • 職種の垣根をこえて進められる
  • 開発フェーズ
    • 最初から実機で進めている
    • シミュレータでは感じられない操作感などがわかる
    • デザイナーに見てもらうときも、いろいろな実機をもっていく
      • ヘルプデスクから端末を借りられる
  • テストフェーズ
      1. 社内自動ビルドシステムを利用
      2. 社員はみんなiPhoneを持ってる
      3. Before/Afterをチームメンバーのために作っている
      1. 前バージョンからの変更をコードで見る
      2. PRとは別に差分をみて変更を把握する
      1. QAによるTestFlightを利用したテストケース
      2. 大きな差分がある場合は外部に依頼することも
        • 端末の網羅性など
        • お金がかかるので不安が消えないときなど
      1. iTCのプロモーションコードによるリリース直前チェック
      2. 審査が通ったあとも最終確認
      3. アップデート時にマイグレーションで落ちることも
      4. クラッシュレポートなどを確認
        • 浸透するには4日間くらい
      5. アップデートの評判を聞く
      6. 一部はアンケートをとったり
  • 天気アプリならでは
    • 天気情報を見せるのがメイン
    • 入力などはないのでそのあたりのセキュリティなどの考慮はあまりない
    • プラットフォームが整っている
    • 生活の一部
      • 毎日起動されるアプリなので、見た目の品質が重要
      • ユーザは細かいことでも気になる
  • コンテンツの品質
    • 災害発生時の動き
      • 8面モニタで情報収集をしている
        • 災害発生時にすぐに分かるように
    • サービスマネージャが天気予報士の資格を持ってる
      • 予想しながら動くことも
    • アプリチームは?
      • ユーザが必要そうな情報は発信
      • 手動で通知をうって、ユーザに知らせる
        • チャット上で通知の文言を相談する
        • 事実を提供する
      • 災害時
        • 一部はWebViewなのでデザイナが更新できる
        • 災害が落ち着いてから情報が十分だったか振り返り
    • ピンチのときにユーザを助けてこそ会社の信頼につながる
  • まとめ
    • 少人数PJを支える強力な社内システム
    • 見た目に徹底
    • MixLeap
      • 大阪2拠点になります
      • 毎週イベントを開催している
      • フォロー歓迎(Twitterアカウント)

私も普段から利用している「Y!天気」アプリの発表でした。

まず、iOS/Androidエンジニアが1名ずつという点に驚きました。そういった少人数でも品質を保つ大勢や仕組みが非常に参考になりました。

参考になることばかりだったのですが、あえてピックアップするとすれば以下が特に参考になりました。

  • 前バージョンからのコード差分を見る
  • 毎日起動されるアプリなので、細かいUIについても拘る
  • サービスマネージャが天気予報士の資格を持っている

当たり前な品質を支える様々な仕組みと、天気というサービスに特化した品質の考え方が取り入れられていて、とても戦略的にサービスを開発・運用しているのだと強く感じました。

iOS アプリエラー監視のための設計と効果

speakerdeck.com

  • 自己紹介
    • 開発速度を2倍にした
    • 趣味はTODO
  • エラー監視とは?
    • アプリで発生したエラーをサーバに送る
    • クラッシュレポート
    • Crashlyticsなど
  • クラッシュ以外のエラーも監視できる
    • 内部状態の不整合とかも
  • エラー監視の特性
    • 広範なバグを検知
    • 発見が遅い
  • バグが埋め込まれてからの時間が短いほうが嬉しい
    • 特殊ケースのバグは発見が遅くなる
    • 下から2つ目
      • 最後の砦
      • ユーザからの問い合わせはあるいみNG
  • 理想のバグ検知
  • ダメ検知
    • 発見までの時間が長くなる
    • エラー監視は特殊なバグを検知する手段
      • それ以外はそれより前のフェーズで見つけるべき
    1. エラー監視サービスのAPIを把握
    2. Crashlytics以外でもAPIドキュメントを探そう
    1. エラーレポーターをカスタマイズ
    2. NSErrorではなくSwiftのErrorで送信できるように
    3. 発生元のオブジェクトを渡す
    4. DEBUGと本番を分ける
      • DEBUGでも送信したほうがベター
      • 区別できれば良いのではないか?
    5. NSErrorへの変換
      • domain/codeで設定される
      • 発生元をreporterとしてdomainに含める
      • エラーメッセージを含めてはいけない
        • 同じ不具合が別のバグとして分類されてしまう
  • 実際に組み込む
    • ハードコード
      • 単一責務原則に違反する
      • 単体テストでエラーレポートが送信されてしまう
      • isTestフラグ
    • Observerパターン
      • エラーReporterを監視者として、エラーが発生したら送信
      • テストの時にはエラーレポーターを使わない
      • Observerパターンを使える場所は限られる
        • Modelはだいたい監視できる作りになっているはず
      • RxのObservableを使っている
    • エラー監視にはObserverパターンが適している
  • 困ったケース
    • Fatal Exception
    • エラーにはなるべくクリティカルな情報を含める
    • 原因究明をわかりやすくする
      • nilを返すのではなくenumを返す
  • 結果
    • ユーザの手元で発生しているバグの種類や規模を把握できるようになった
      • 重要度のジャッジが出来るようになった
    • ユーザの手元では予想外のエラーが起こっていることに気づく
      • 特定のキャリア回線で発生する不具合など
      • Sandboxのレシートじゃないと再現しないとか
    • 副作用
      • テスターの動作確認中にエラーレポートが飛んでくる
  • まとめ
    • エラー監視で、テスターが発見できない不具合が発見できる
  • 宣伝
    • ランチ募集

モバイルアプリの開発において、避けては通れないエラー監視をどのように扱うか、またどのように設計したら良いかという発表でした。

Twitterのタイムラインでも話題になっていましたが、エラーの種類とそれがどこで発見されるべきかという図がとても分かりやすかったです。こういったことは開発が忙しくなると特に忘れがちなので、こういった図にまとめられているととても良いと思いました。(チームメンバーが見える位置に貼っておくというのもありかと思いました)

そしてエラー監視の設計についてはObserverパターンを利用すると良い、という話が後半でした。Observerパターンを採用することで、単一責務の原則を守ることが出来て、かつ不要なときは観測者(Observer)を外せば良い、という考え方はよくできているなぁと思いました。

あと、エラーレポートに詳細なメッセージを含めない、DEBUG環境でも区別できるようにした上で送信してしまう、というのも参考になりました。(私が以前関わっていたiOSプロジェクトでは、DEBUG時は送信しない設定にしていました)

スタートアップでのQA

  • 自己紹介
    • QAエンジニア10年
    • Six Apart
    • TORETA
      • 飲食店向けの顧客サービス
      • iPadでスケジュールを管理する
        • 顧客データがたまるメリットも
        • 集計・分析にも利用できる
        • ウェブ予約との連携も
        • 一元管理できるのがメリット
  • QA?
    • 会社や組織によってまちまち
    • 入社時の肩書として、QAエンジニアを選んだ
      • プロダクトの品質を広範囲でサポートしたい
      • テストは品質保証の一手段
  • 2年間でやったこと
      1. 顧客を知る
      2. 実際になにが大変で、どういった使われ方をするのか
      3. 営業同行+新機能のヒアリング
      4. データから利用状況を知る
        • BigQuery
      5. バグのトリアージ
      1. 価値の高いテストに集中する
      2. テストに限られるリソースは限られている
      3. 関係者を巻き込む
        • セールス・サポート:おさわり会
      4. E2Eテストは同じリポジトリで管理
        • QAエンジニア以外でもテストコードをかけるように
      1. 自動化
      2. 時間ができたら自動化に取り組む
      3. テスト・デプロイの自動化
      1. 開発・運用の持続可能性を高める
      2. TORETAはプロダクトのライフサイクルが長い
        • 5年・10年、それ以上も?
      3. ドキュメント
        • 書くのもメンテするのもかなりのコスト
        • 書きすぎないを意識(問い合わせがあったら書く、くらいの感覚)
      4. 手動テストケースを追加した理由を残す
        • 長く時間が経つと、なぜ追加したのかわからなくなることも
        • Markdownで書いて履歴として管理する
      5. 長くプロダクトを育てていくために
      1. 製品の課題をサポートで補完する
      2. B2Bなので顧客に直接連絡できる
      3. サポートチーム経由で店舗にヒアリングできる
      4. サポート対象バージョンを絞る
        • セールス経由で店舗側でアップデートしてもらうことも出来る
      1. サポート運用の課題を技術で解決する
      2. サポートの意見を製品に活かす
        • サポートチーム、アカウント管理チームと週1ミーティング
        • お知らせ機能
        • 問い合わせ番号
        • 設定画面の文言改善
  • まとめ
    • スタートアップは総力戦(みんなで協力する)
    • 顧客のことをよく知る
    • 価値が高いことに集中する
    • プロダクトの問題をプロダクトだけで改善しない
      • プロダクト品質 x サポート品質
    • お隣さんとはアイディアが眠っている

飲食店向けのiPadで予約管理できるサービスにおいて、QAエンジニアとしてどう関わったかという発表でした。QAエンジニア歴10年ということで、参考になる話ばかりでした。

個人的には、顧客やプロダクト、サービスの性質(ライフサイクルが長い、B2B)を考えた上での取り組みが行われていることが、とても素晴らしいと感じました。とくに「顧客のことをよく知る」というのは品質を考えていく上でとても大切なことだとあらためて思いました。

ちなみにテストケースをMarkdownでバージョン管理するというやり方は、以前取り組んだものの失敗した経験があるので、機会があればもう一度挑戦してみたいなと思いました。

QA組織とiOSのテスト

speakerdeck.com

  • 自己紹介
    • LINE株式会社
    • サービスQAチーム
    • LINEファミリーアプリを担当
    • QAエンジニア歴9年
    • 社内インタビュー
  • QAエンジニアのロール
    • QA?
      • テスト管理全般をする
      • 上流からどういうテストが必要可考えて、プロダクトの品質を評価
      • SET
        • テスト自動化
      • Tester
        • 手動テスト
    • QAエンジニアに必要なスキル
      • 幅広いスキルセットが必要
    • チームにQAとしてアサイ
    • 静的テスト
      • インスペクション(仕様レビュー)
      • 欠陥の防止
    • 動的テスト
  • 品質評価の考え方
    • リリース判定の考え方
    • Webアプリとは異なり、ロールバックが即座にできない
    • 品質の推移を測定
      • メトリクスを取る
    • 信頼度成長曲線
      • リリースにはバグカーブが収束していること
    • スクリプトテストの予実管理
      • すべてのテストがパスすること
    • メトリクスの落とし穴
      • 不具合が収束していないからと言って品質が不十分であるとは限らない
    • 品質モデル
    • テストと開発者は協業したい
    • QAはできるだけ開発が開発に集中できるように
    • 開発の品質に対する不安をなくしたい
  • 取り組み
    • テストケースの見える化
    • テスト実行結果
    • テストケースは誰でも見えるように
  • テスト結果とBugを紐付ける
    • どのテストによってBugが生まれたか開発者がわかりやすい
  • グレーボックステストのアプローチ
    • 課題
      • BTSを見ただけでは何を修正すればいいかわからない 
      • バグレポートの制度を上げる
      • テスターにもAPI Referenceを読んでもらう
  • iOS固有のプラットフォーム
    • テストしている側がプラットフォームを理解していない
    • テスターもヒューマンインターフェースガイドラインを読む

QA組織としてどのようにプロダクトの品質を判定、リリースしているかについての発表でした。

BTSなどのメトリクスをきちんと測った上で、QCDとのバランスを考えた上でリリース判定しているというのが非常に良いと思いました。

私は以前とあるプロジェクトで開発していた時にQA組織がメトリクスを測っていたのですが、とてもレアケースな不具合が(一般的に想定される利用ケースではまず発生しないようなもの)多くあったことを理由に品質が不十分であると判定された経験がありメトリクスについては懐疑的でした。(QA組織はきちんと仕事をしてくださった、とも言えますが)

今回の発表ではメトリクスを測った上で、それだけを正解(あるいは正義)にしていないのが個人的にはとても好印象でした。

あと品質の見える化を行うというのは、とても良い試みであると感じました。

SmartNewsアプリの品質

www.slideshare.net - 自己紹介 - 荒巻 賢一 - 趣味:いろいろ - SmartNewsの品質 - ニュースコンテンツへのこだわり - アルゴリズムを改善し続ける - 広告へのこだわり - 広告もコンテンツの一部である - ピクセル単位で調整したり - 開発 - ブランチ:git-flow - pushでXcode Serverでビルド&テスト - prototypeでベータ配布 - スプリント - iOS/Androidで2週間単位 - QAは1週間単位で交互にテスト - iOSの標準に従いつつ必要なら変更 - けい素解析で折り返し - なめらかなページめくり - BTS - Apple Developer Technical Support事例 - iOS 9.0のみでクラッシュ - WKWebViewのキャッシュがたまり続ける - アプリ実装のこだわり - 星マークの歪み - AppStoreでは正方形に内接(星としては歪み) - クリスさんより(XCUITest) - ゴールデン街に詳しい人はぜひ - ビルドサーバの構成 - サーバは2台 - Productionビルド用 - Testビルド用 - Xcode Serverの次バージョンを確認 - 問題なければProductionにインストール - 本物のハードウェアやシミュレータでUIテスト - UIテストは時間がかかるので、Production用のビルドに影響しないように - XCUIAutomation - Obj-C - accessibilityIdentifier: ローカライズに依存しない - accessibilityLabel: 目が見えない人のため - VoiceOver用のステートが入っている - ツール - push simulation - log exposure - Swiftでユーザの操作のようにテストが書ける - enumが使いやすい - nestedなenumにするとコード補完で画面のエレメント構造がわかる - namespaceとして使う - Objc-Cブリッジが不要 - アプリ内のステートを公開する必要はない - 世界中の良質な情報を届ける

SmartNewsアプリの品質への考え方や取り組みについて、2名からの発表でした。

前半はSmartNewsアプリの品質についての取り組みについての発表でした。

SmartNewsはアプリ実装について結構なこだわりを持っているとのことで、なめらかなページめくりや良質な見た目など、UI/UXにとてもこだわっているとのことでした。このあたりは求められる(あるいは目指す)品質が、プロダクトやサービスなどによって全く異なるということをあらためて思い出させてくれました。

後半はビルドサーバやUIテストの実装についての発表でした。

ビルドサーバは2台構成にしていて、新しいものを導入する時には1台のマシンに導入した上で、問題がなければ新しいマシンにも導入する、といったビルド環境を壊さないようにする取り組みは参考になりました。

XCUITestについては、enum名前空間(ネームスペース)として利用する方法は良いなと思いました。静的型付けでIDE上でコード補完が効くSwiftという言語を有効活用した、良い方法だと思いました。

ところでSmartNewsは「世界中の良質な情報を必要な人に送り届ける」というミッション(あるいはビジョン?)を持っているそうです。

”船を作りたければ、海へのあこがれを説け”という有名な言葉がありますが、プロダクトやサービスがこうした向かうべき方向についての軸を持っているのは重要だとあらためて思いました。

短期大規模開発の品質とスピードの両立について in ライブコマース

  • 自己紹介
    • ショッピングのiOS
    • トラベルのiOS/サーバサイド
  • 開発工数3ヶ月で無事故でライブコマースを乗り切った
  • ライブコマース?
    • アプリをタップするとライブ動画が配信される
    • いいね、コメントなどを複数のアプリで共有する
  • ライブ配信
  • やることいっぱい
    • 何からスタートした?
    • デモ関係
      • デモ用アプリを作成
      • デモ要配信サーバを構築
      • デモ用のSocketサーバを構築
    • アプリ側
      • OSSを利用
      • LFLiveKit, socket.io-client.swift
    • ライブ配信サーバ側
      • NGINX
      • nginx-rtmp-module
  • デモアプリのメリット
    • 完成のイメージを固められた
    • 実現への自信が持てた
    • 社内での説得力がます
      • 有識者とのコミュニケーションもできた
    • コードを流用できる
      • 実際に本番コードに組み込んで流用
    • 簡易動作確認環境
      • 問題の切り分けに繋がった
    • 品質・スピードを上げることができた
  • テスト
    • 本番同等環境を使った
    • 50人一斉視聴テスト
      • メールや口頭で人を集めた
    • 実際に出た不具合
      • 端末が熱い
        • Socket接続のエラー時に再接続がされていなかった
        • インスタンスが更新されていなかった
        • フラグを追加すれば解決した
      • いいね(iPhone 5
        • 乱数の生成に問題があった(32bit)
      • ライブ視聴を繰り返すとクラッシュ
        • AVPlayerの破棄がされていなかった
        • 初期化するだけで解決
  • 振り返り
    • Good
      • ミニマム開発から広げることができた
      • 社内から知見のある人を見つけることができた
      • 精度の高いテストができた
    • Bad
      • 省いたところはある

ライブコマースという、アプリからライブ動画を見れて、そこでの「いいね」やコメントなどを複数アプリ感で共有する機能の開発を短期間で行った際の取り組みについての発表でした。

よく言われることですが、実際に動く簡易版の実装を行うことはとても大切、かつ効果的だとあらためて思いました。特に自信への繋がりや、有識者とのコミュニケーションに繋がったのは、とても良いと思いました。

あとは社内で利用者を集めて、本番同等の環境でテストを行うという取り組みはとても良いと思いました。やはり開発時には気づかない不具合も出てくるので、品質を上げるためにはそうした取組は必要だと思いました。

全体を通して、とにかく戦略的に開発を行ったのだという空気を強く感じました。

懇親会

お寿司を頂きました、美味しかったです!

感想

あまり他のiOS勉強会では話題に上がらない「品質」というテーマで、バラエティに富んだ発表を数多く聞くことが出来てとても有意義な勉強会でした。

私があらためて思ったのは、プロダクトやサービスによって品質の考え方は異なるということでした。画一した「品質」というものは存在せず、品質の考え方については結局自分たちで考え抜かなければならない、ということです。

それを実現する上で、様々なプロダクトやサービスにおける実際の取組みが聞ける、というのはとても良いことだと思いました。(おそらく発表者の方々も、他の発表で得るものがあったのではないかと思います)

勉強会の企画・運営をしてくださった方々にお礼申し上げます。

蛇足

久しぶりのブログのせいか、なんだか文章が稚拙な気もしますがご容赦を。

Androidで利用されるGradleバージョンの確認方法

AndroidでGradleのバージョンと言った場合、以下の2種類がある。

Gradle本体

Gradle本体のバージョンは、File > Project Structure > Projectから確認できる。 f:id:yu_dotnet2004:20170804131110p:plain

利用可能なバージョンは以下のURLから確認可能。 https://services.gradle.org/distributions/

gradle/wrapper/gradle-wrapper.propertiesdistributionUrlを変更することで、新しいバージョンの利用が可能。(gradlewがラッパーになっており、自動的に記載されたバージョンがダウンロードされる仕組みになっている)

#Mon Apr 17 18:32:32 JST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.5.1-all.zip

例えば上記のように指定して、./gradlew buildすると自動的にダウンロードされてbuildタスクが実行される。

$ ./gradlew build
Downloading https://services.gradle.org/distributions/gradle-3.5.1-all.zip
...
$ ./gradlew --version

------------------------------------------------------------
Gradle 3.5.1
------------------------------------------------------------

Build time:   2017-06-16 14:36:27 UTC
Revision:     d4c3bb4eac74bd0a3c70a0d213709e484193e251

Groovy:       2.4.10
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.8.0_121 (Oracle Corporation 25.121-b13)
OS:           Mac OS X 10.12.6 x86_64

Android Plugin for Gradle

GradleのPluginとして実装されているもの。

トップレベルのbuild.gradleに利用するバージョンが書かれている。

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.2'

利用可能なバージョンは以下から確認できる。(Gradle本体の必須バージョンも書かれている) https://developer.android.com/studio/releases/gradle-plugin.html

Gradle本体のケースと同様にファイルを書き換えて、Android Studio上からSyncすればOK。

参考URL

http://qiita.com/izuki_y/items/3c20cd1c655fc4fc6127

platform-tools について復習

なんか微妙に理解が怪しくなったので復習。

なに?

adbとかfastbootといったコマンドが含まれるツール群。

インストール

Android StudioSDK Manager からインストール・アップデートできる。 f:id:yu_dotnet2004:20170804122624p:plain

最近は SDK Manager を利用せずとも単独でダウンロードできるらしい。 https://developer.android.com/studio/releases/platform-tools.html

含まれている主なコマンド

adb

android debug bridgeの略。 apkをインストールしたりデバッグしたりまぁいろんなことに使う。

fastboot

  • Fastbootモードという、PCでいうところのBIOS画面のようなものがある
  • 端末がそのFastbootモードで起動していれば、fastbootコマンドで操作することが出来る
  • adb reboot bootloaderコマンドで、再起動後にfastbootモードで立ち上がる
  • フラッシュメモリへの書き込みや、フラッシュメモリ上のパーティションの管理などが行える
  • カスタムリカバリの書き込みを行うことも出来る

参考URL

https://jagadgetaholic.blogspot.jp/2015/12/fastboot-command.html http://news.mynavi.jp/column/androidnow/043/

iOSDC JAPAN 2017 に CfP を出してみた

iOSDC JAPAN 2017 に CfP を 3本出しました。 iosdc.jp

”当たらなければどうということもない”なんて名セリフもありますが、たしかに当たらなければ発表できません。 (悲しいけどこれ抽選なのよね)

なのでせっかくなのでシェアしたいと思います。 もし「これ聞きたいかも」と思うものがあれば、リンク先のページでブックマークやらTweetしていただけるとです。

実践テスト駆動開発 in iOS 15分 or 30分

iosdc.jp

TDD(テスト駆動開発)をご存知の方も多いかと思いますが、iOSではあまりテスト駆動開発の適用例を聞かない気がしています。 おそらくその理由の一つとして「UIが頻繁に変わるから向いてない」ということなのでしょうが、果たして本当でしょうか?

iOSにおけるUIテスティングは確実に進化しています。

本セッションではライブコーディングを取り入れながら、 実際にどのようにテスト駆動開発を適用していけるかをステップ by ステップで紹介したいと思っています。

UIテストの実行時間の短縮に挑戦する(LT)

iosdc.jp

UIテストを作成することで、リグレッションテスト(回帰テスト)の自動化といった恩恵を受けられるようになります。

しかし、往々にしてUIテストは実行時間がネックになります。 個人的な意見ですが、”実行に時間がかかる”というのは見た目以上のコストがかかっており、実際に掛かった時間以上のものを奪うと思っています。 (モチベーション、集中力低下によるパフォーマンスの低下、etc)

本セッションでは、UIテストの実行時間をどこまで短縮できるか挑戦した結果を発表したいと思います。 それによって、実際の開発にUIテストを導入する障壁を少しでも低くすることができればと思っています。

Swiftzで学ぶ関数型プログラミング

iosdc.jp

ここ数年で関数型プログラミングはかなり注目され始めています。

Swiftを作る際には関数型言語Haskellが参考にした言語の一つとして紹介されていますし、 実際、Swiftは関数型プログラミングパラダイムとしてサポートしています。

しかしながら、関数型プログラミングなかなかとっつきづらく難しいテーマであるのも事実です。

本セッションではSwiftでの関数型プログラミングをサポートするライブラリである「Swiftz」を用いつつ、 関数型プログラミングとはどういうものかという入門的なお話をできればと思っています。

最後に

まぁそんな感じです。よろしくお願いします。