Guild icon
swift-developers-japan
main / testing
Avatar
Happy happy testing!
🙌 8
Avatar
かっくん 12/6/2017 6:49 AM
NSAssert("#testing".existing)
Avatar
XCTAssert(everybodyDoingTesting)
Avatar
いつの日にか通ってほしいものですねw
6:55 AM
とりあえず、賑やかし的に前に発表した「iOS でテスト容易な設計を
実現するためのデザインパターン」を貼っておきますー https://speakerdeck.com/orgachem/ios-detesutorong-yi-nashe-ji-wo-shi-xian-surutamefalsedezainpatan
Avatar
オススメのテストの本とかもAmazonのリンクがあれば貼ってもらったら
6:56 AM
だれか買うはず
Avatar
かっくん 12/6/2017 6:56 AM
ちょうど明日社内のエンジニア向けにこのビデオの視聴会しますー
Avatar
2倍速なのでお気をつけくださいw
Avatar
:orecon:
Avatar
オススメの本ですか、何にしようかな
6:58 AM
iOS の本ではないですが、単体・結合・UIテストで何をテストし、どのように使い分けるかという考え方が易しく開設されています: https://www.oreilly.co.jp/books/9784873118161/
Webシステムの自動テストを始めたい方を対象に、自動テストの考え方やフレームワークを解説する書籍です。テストのピラミッドやユーザーインターフェイステストの概念など、基礎的な事柄から、レガシーシステムへのUIテストの追加、RESTfulなWebサービスのテスト、ブラウザ上のJavaScriptの挙動をユニットテストでテストする方法など、実践的な事柄までを豊富なイラストとサンプルを使って分かりやすく解説します。さらにテストファーストやモックの活用法、テスターに向けた自動テストのためのプログラミング基礎知識なども詳述。自動テストを書くためのノウハウを網羅した本書は、自動テストをマスターしたいエンジニア必携の一冊です。
Avatar
お、積ん読してるやつw
Avatar
また、ある程度単体・結合テストを書いた方向けには、テストの効率化のパターンとして xUTP をお勧めしています。 http://xunitpatterns.com/
Avatar
(Kindleに突っ込んでて読むの忘れてるやつ…)
7:00 AM
xUTPは面白いので僕もオススメ
Avatar
あれ一章だけでいいので、邦訳したの欲しいですよね…そうすれば敷居がぐっと下がります
Avatar
たしかに洋書ってだけで敷居高い感じはしますよね。著者に翻訳させてくれと言えば翻訳させてもらえる事例もあるので、聞いてみたらいいかもですね
Avatar
ですね!
Avatar
かっくん 12/6/2017 7:05 AM
(勝手に期待しておく)
Avatar
ウッ
Avatar
実は、「iOS テストライブコーディング道場」という勉強会をやろうとかモヤモヤ考えています。みんなでテストできないコードを持ち寄って、識者数人で喋りながらテストをライブコーディングするというものです。
👍 3
👀 1
9:31 AM
こうしたらもっと面白くなりそう、とかご意見をお待ちしております。
Avatar
テストに対して問題を感じる程度に規模があって、かつ公開できるコードを持ってる人ってどれくらいいるんだろう…w
Avatar
ぼやかしたコードを持ち寄ってもらえればいいのですが、その手間がきつそうなんですよね…
Avatar
その手間でテスタブルにリファクタすると思う…w
Avatar
ひとつのお題に対して、みんなでテスト書いてみる、の方がやりやすそう
9:37 AM
みんなそれぞれ書いて比べる、みたいな
Avatar
なるほど、個人的にはテスト書くのを識者限定にしたくて、なるべく敷居を下げたいですね
9:38 AM
テスト書いたことのない人も参加対象になって欲しいのです
Avatar
ターゲットによりますね。 普段テスト書いてる人はもちろんくると思いますが、普段書いてない(が書き方がわからないだけで書きたいと思っている)人も呼びたいのか、日頃から書いている人限定にしたいのか
9:39 AM
あ、かいてたw
Avatar
ですです!
9:40 AM
実は社内で複数回開催していて、テストライブコーディング自体には手応えを感じているんです。問題はお題なんですよね。。。
Avatar
持ち寄りにするとレベル上がっちゃいますね
Avatar
そうですね。やはり、ある程度運営側がお題を用意する必要がありそうですね
Avatar
その辺は手探りでOKだと思うので、まずは開いてくださいお願いしますw
Avatar
いくつか手持ちはあるので、最初はそれ使えばよさそうですね
9:43 AM
オンライン/オフラインは悩ましいですね。最終的にはオフラインへ持っていきたいですが、Swift Tweets 見てると手軽でいいなぁ、と思うんです
9:44 AM
オフラインの課題はライブコーディングインフラですね
Avatar
↓みたいなのがあればいいんでしょうか? https://japan.cnet.com/article/35110495/
マイクロソフトは、開発者がリアルタイムでコーディング作業を共有できる新サービス「Visual Studio Live Share」に関する情報を公表した。
Avatar
そうですね!イメージは大体合ってます。あとは視聴者側の障壁が低ければなおいいですね。
Avatar
米GitHub Inc.は15日(現地時間)、コードエディター「Atom」でソーシャルコーディングを実現するパッケージ「Teletype for Atom」をベータ版として公開した。ソースコードの編集をチームでリアルタイム共有できるようになる。
Avatar
Atom!!!! 最近話題になってましたね!
Avatar
前にオンラインでできるやつを使ったことがあるんですが、名前が思い出せず・・・
Avatar
ありがとうございます。情報提供、非常に助かります。
9:54 AM
これかしら
Avatar
それそれ。
9:54 AM
Swift のシンタックスハイライトがないけど・・・。
Avatar
でもだいぶいいですね!参加者は名前入れるだけなので懸念していた参入障壁の問題をクリアできそうです
9:56 AM
おお、Rx
Avatar
omochimetaru 12/6/2017 9:57 AM
あ、これは自作のです
9:58 AM
ReactiveEmitter - Lightweight observable in Swift seen from EventEmitter in JavaScript.
Avatar
はい、会話からするとそうだろうな、って思ってました。Convertible と Sink から Rx の心臓部っぽさがありますよね。
9:59 AM
お、この感じ Alt Reactive Library...!
10:00 AM
ああ、Node.js の EE + Rx Ops を目指しているのですね。
Avatar
はい
10:00 AM

導入

この記事では JavaScript の EventEmitter から出発して、それをバインディングパターンを見据えて改良していく過程で Rx になる話を書くことで、両者が近縁な存在である事を示します。実装は Swift ...
10:00 AM
ストリーム指向というわけではないがリアクティブな設計はほしいよね、みたいな気持ちになるときがあって
10:01 AM
そっちの観点で整理してみようとしてやってます
10:01 AM
なのでエラーは流れないし無限ストリーム限定でRxよりシンプル。
Avatar
ですね。単なる Observer パターンに Cold Obsbervable はいらないですからね。
10:02 AM
私も Delegate から出発して同じことをしようともやっと考えていました。
Avatar
ほうほう
Avatar
いつか形になったら、ここで披露しようと思います
10:03 AM
ちょっと脇道に逸れてしまったw
10:09 AM
動き始めるのは来年でちょっと考えてみようと思います。
👍 2
10:09 AM
アドバイスをくださった皆様、ありがとうございました!
Avatar
テストのつらくない導入戦略についての社内向け資料を、一般に公開しました。テストのないプロジェクトでは参考になると思います。 / “コスパで学ぶ自動テストのはじめ方 - 若き JavaScripter の悩み” http://htn.to/BULVvm
Qiita 週間ランキング1位を獲得しました Kuniwak です。ご愛顧ありがとうございます。 qiita.com さて、本題に移りたいと思います。 つい最近ですが、勤め先の別チームに向けて自動テストの導入を支援するための資料を作成しておりました。こちらを共有したいと思います。 speakerdeck.com 資料中にある「仕様化テストを推奨しない」という決断には賛否両論あるかと思います。仕様化テストを推奨しなかった理由は、仕様化テストにかかるコストは相当に高く、本当に余裕があるときでないと選べない選択肢だったからです。今回自動テストを導入しようとしているチームは、見るからに余裕のない状況だ…
👍 9
Avatar
これいいですね!特に良い設計のために↓大事。
テストを書かない時もテストを意識する
Avatar
やったー!ありがとうございます!
🙂 1
Avatar
コスパの話、もやっと感じてたことがうまく言語化されててすっきりしました。 (edited)
😆 1
Avatar
omochimetaru 12/8/2017 4:00 AM
👍 1
4:00 AM
この図めっちゃ良い・・・
Avatar
省エネ資料なのがバレた
🐶 2
😆 2
Avatar
テストについてのぬるいqiita記事を書きました
Avatar
ありがたや🙏
Avatar
書いてみました。ご意見をお待ちしております。🙇 https://dev.classmethod.jp/testing/unittesting/writing-tdd-poker-swift-1/
はじめに おばんです、シリーズとして続けられるかもわからないのに、タイトルに「その1」とかつけてしまいがちな田中です。 今回の記事は、TDDを書きながら学習していくための内容になっています。対象読者は以下の通りです。 「 […]
🙏 2
Avatar
一つのテストケースに複数のアサーションを書いてしまうと、もしアサーションの評価が失敗だったときにどれが失敗したのかがわかりにくいという問題です。 の「詳しくは」先のコメント https://qiita.com/hmhmsh/items/842e795d4b2a41556b5b#comment-a9bd5d57270c1eebfee2 ですが、XCTAssert系は失敗しても止まらないですよ。
みなさん、こんにちは! Swift その2 Advent Calendar 2017 19日目の記事です Swiftでなにか作ろうと...
🙇 1
Avatar
僕は一つのメソッドに山のように XCTSAssert 系メソッドを書いてます。「XCTAssert系は失敗しても止まらない」ので、↓を作ったときは失敗の数が減っていくのを確認しながらバグフィックスしました。 https://github.com/koher/EasyImagy/blob/dev-0.4.0/Tests/EasyImagyTests/ExtrapolationTests.swift (edited)
EasyImagy - Makes it easy to process images in Swift
👍 5
Avatar
うおあ、XCTAssert試してみたら確かに止まらないし、Quickで確認しても同様の挙動でした。追記修正します。 ご指摘ありがとうございます🙇
🙂 4
Avatar
Kishikawa Katsumi 12/25/2017 5:31 AM
厳密にいうとそこ挙動はコントロールできて continueAfterFailurefalse の場合は1つのアサーションが失敗したら、そのテストメソッドはそれ以降実行されない、 true なら続きも実行される。デフォルトは true (edited)
👀 3
Avatar
おお、それ知りませんでした!
Avatar
Kishikawa Katsumi 12/25/2017 5:39 AM
あまり変更することはないけどUIコンポーネントのテストで境界値を網羅しているようなのは1つ失敗すると全部たいてい失敗する(全部44ptずれるとかそういう感じ)のと、実行コストが高いので1つ失敗したら終わるようにしたりします。 (edited)
😀 2
Avatar
なるほど。確かに実行コスト高い系は後続テストを行いたくない場合がありますね。
5:41 AM
そういうときは guard して XCTFailreturn してました。 (edited)
Avatar
Kishikawa Katsumi 12/25/2017 5:42 AM
そうですね。それと1つ失敗したら同じ誤差で全部失敗するようなのはわかるので。
Avatar
continueAfterFailure が false の場合は1つのアサーションが失敗したら、そのテストメソッドはそれ以降実行されない、 false なら続きも実行される。
上げ足を取るみたいになって申し訳ないですけど、どちらも false になってます…。 true なら続きも実行される。ですかね。恐縮っす。
(edited)
Avatar
Kishikawa Katsumi 12/25/2017 11:52 AM
ホントですね。。。
11:53 AM
わけわからなくなってる。
Avatar
XCTAssert系は失敗しても止まらないのもcontinueAfterFailureも知りませんでした...ありがとうございます。🙇
Avatar
Discussion The default is true. Set this property to false within a test method to end test execution as soon as a failure occurs. https://developer.apple.com/documentation/xctest/xctestcase/1496260-continueafterfailure
Avatar
func urlOrNil1(urlString: String?) -> URL? { guard let urlString = urlString else { return nil } return URL(string: urlString) } func urlOrNil2(urlString: String?) -> URL? { return urlString.flatMap(URL.init(string:)) } 後者の書き方を使うことが多かったのだけど、前者だとnilを返すパターンをテストできてるかどうかcode coverageを使えばチェックできる事に気付いた。
Avatar
確かに!
Avatar
僕も昔はよく OptionalmapflatMap を使ってましたが、今はほとんど guard let 使ってます。可読性のために。 ?. も必要最小限しか使わないですね。
1:49 AM
一方で、 Forced unwrapping は必要なケースでは( nil になるのがロジックエラーなら)よく使います。できるだけ、それが nil にならない理由をコメントをつけるようにしています(本当はコメントではなくエラーメッセージにしてくれるものがあれば標準であればいいですが)。
1:50 AM
ああ、 #testing からずれてしまいました。
1:50 AM
! を含むロジックエラーは Swift でテストできないのが難点ですね。
1:51 AM
precondition に引っかかることをテストしたいこととか結構よくあります・・・。
Avatar
お、テストできない理由、気になります
Avatar
precondition に引っかかったらクラッシュしちゃいません?テストで precondition 等の失敗をハンドルする方法あるんですっけ?
1:52 AM
! の失敗も。
Avatar
あ、意味がわかりました。異常系のテストでテストを継続できないという話ですね
Avatar
はい、↓のようなケースで、 x に負の数を入れて正しくエラーになることをテストしたいです。 func foo(_ x: Int) { preconditon(x >= 0) // x を使う処理 }
1:53 AM
Java だと RuntimeException なので catch できるんですが・・・。
Avatar
愚直に考えると precondition をテストダブルで置き換える形になりますが、可読性が犠牲になりますね
Avatar
Swift がロジックエラーを取り扱う方法を提供してくれるのがいいと思うんですよね。 SSS とかでも、最悪エラー発生しても落とさないようにするとかできないときつい気が。 (edited)
1:55 AM
あ、 actor でそれができるようになるのかな・・・。 Proposal 読んでないのでよくわかってないです。
Avatar
Proposal 読んでみます
1:57 AM
Erlang だとクラッシュしても Erlang プロセスの範囲で死ぬので全体がクラッシュすることはないとか(だったはず)ですが、 Swift の actor がどうなってるのかわからないです。
Avatar
つまり、スレッドや子プロセスが死ぬ範囲で収まるのでテスト側はテストを継続できるということですね
1:59 AM
これ、今でもできてりしないですかね。DispatchQueue で別スレッドが死んだ場合どうなるかを確認したことないので試してみます
Avatar
はい、 Erlang 詳しくないですが、 Erlang では let it crash といって Erlang プロセス単位でクラッシュさせてエラーハンドリングしたりする(なずな)ので、 try/catch 的なノリでクラッシュさせてるんじゃないかと思ってます。
2:01 AM
Swift の actor で precondition! の失敗を階層的に食い止められるようになるならかなり良さそうだと妄想してます。
Avatar
omochimetaru 1/16/2018 2:07 AM
これ、今でもできてりしないですかね。DispatchQueue で別スレッドが死んだ場合どうなるかを確認したことないので試してみます
基本的にクラッシュはシグナルレベルなんでプロセスレベルで全滅します
2:07 AM
スレッドだけ死ぬとかではないです 残念ながら
2:07 AM
まあスレッド同士でメモリ空間を共有しているのでそうでないと連鎖的に崩壊するはずです
Avatar
あまり詳しくはないのですが、signal ハンドリングはできない感じです?
Avatar
omochimetaru 1/16/2018 2:07 AM
お。
2:07 AM
CのAPIでやればできるはずです!
2:08 AM
OSごとの実装になるけど。
2:08 AM
ただ、例えば、返り値Neverの関数の呼び出し以降のコードは「絶対に実行されない」って仮定をオプティマイザが置いてその先のコード削除が起きたりするんで
2:08 AM
そういう最適化との兼ね合いが起きる変数とかが他のスレッドでもアクセスが有ると
2:09 AM
あるスレッドの死をシグナルハンドラで不正でも、そこから先は未定義動作があちこちで生じうるのでヤバそうです
Avatar
まだ理解しきれていないですが、やばそう感は感じます
Avatar
omochimetaru 1/16/2018 2:10 AM
シグナルハンドラって関数として登録するんですけど、CPU命令のタイミングでフックされて呼び出されるわけで
2:10 AM
そこで死なずに戻ってきたとして
2:10 AM
例えばそのシグナルが発生してる例としては
2:10 AM
var x: String? = nil var y: String = x!
2:11 AM
↑こういうコードがあったとして、2行目の右辺値の評価中に ! のところで x がnilだからシグナルで死ぬわけです
2:11 AM
てことは、ハンドラで蘇生して戻ってきたとしても
2:13 AM
nilのメモリ(おそらくここでは0で埋まった24バイトの連続メモリ)
2:13 AM
を、Stringとみなして無理やり読み取って続きの処理が走ろうとするんで
2:14 AM
内部バッファを指すポインタも0になってるから、 文字を読み取ろうとした時点で今度はnullポインタによるメモリアクセス違反のシグナルが飛んでくるとか
2:14 AM
そういう感じになると思います
2:14 AM
あ〜、シグナルハンドラの時点でスレッドを殺しちゃえば
Avatar
あー、なるほど。その時点で thread の破棄が可能かどうかとかを考えています
Avatar
omochimetaru 1/16/2018 2:14 AM
いいのかな?
Avatar
です、詳しくないのでできるかどうかはわからないのですが
Avatar
omochimetaru 1/16/2018 2:14 AM
多分そうすると今度は、Swiftレベルで必要なデストラクタの呼び出しがスキップされて
2:14 AM
メモリリークとかが起きますね
Avatar
リファレンスカウンタがヤバそう・・・
Avatar
omochimetaru 1/16/2018 2:14 AM
スタック上の変数を解放して参照カウンタを減らしたりしないといけないんで
2:15 AM
ヒープ上に残り続けるオブジェクトが出てきます
Avatar
テストなので、プロセス寿命が短いためそこまで問題にはならなそうですね
Avatar
omochimetaru 1/16/2018 2:15 AM
あ〜なるほど
2:15 AM
死なないアプリケーションを作るんじゃなくてテストのためだったら
2:15 AM
なんか応用の余地があるかもしれません
Avatar
なんにせよ、そこまでするコストがリターンに見合っているかというと微妙なのが難しいところですね
Avatar
@omochimetaru
なんか応用の余地
まさに↑で書いてた precondition にひっかかるテストはできるかも。
Avatar
Kishikawa Katsumi 1/16/2018 2:17 AM
私はprecondition()やfatalError()のケースをテストしようと悩んだ時期もあったのですが今は諦めています。すげ替えるのが一番簡単なんですけど、それもデメリットが大きいと思っているので。
Avatar
fork して子プロセスの exit ステータスコード調べる方が楽な気がします。
Avatar
はい、しかし iOS でもできましたっけ…?
Avatar
あー、iOS ですね。なるほど。
Avatar
Kishikawa Katsumi 1/16/2018 2:18 AM
MacプロジェクトならOKですね。
Avatar
今 Dispatch 調べてたんですが、DispatchSourceProcess というものがあるんですね。これ使えたりしそう…?
2:23 AM
スレッドじゃなくて子プロセスなら話は随分簡単になりそうです
Avatar
omochimetaru 1/16/2018 2:24 AM
これはプロセスイベントをDispatchSource化する型みたいだから、プロセスさえ立ち上げられれば結果のハンドリングはこれでできそうですね。イベントは↓があるらしい static let all: DispatchSource.ProcessEvent static let exec: DispatchSource.ProcessEvent static let exit: DispatchSource.ProcessEvent static let fork: DispatchSource.ProcessEvent static let signal: DispatchSource.ProcessEvent
2:25 AM
まあテストだとforkして同期的にwaitpidすれば良さそうですけど
Avatar
はい、それをイメージしています
Avatar
omochimetaru 1/16/2018 2:27 AM
なんかiOSのテスト実行ってUITestでも
2:27 AM
アプリが起動してそのあとテスト関数が叩かれる感じですけど
2:27 AM
もっと昔ってその素体?のアプリが起動してなかったようなきがするんですけど
2:27 AM
昔からアプリも起動してましたっけ
Avatar
Kishikawa Katsumi 1/16/2018 2:27 AM
そこは変わってなくて、ホストアプリを使うかどうかによります。
Avatar
omochimetaru 1/16/2018 2:28 AM
なるほど
2:28 AM
「ホストアプリが無い」状態のプロセスだったらforkできたりしないかな・・・
Avatar
Kishikawa Katsumi 1/16/2018 2:28 AM
ホストアプリを使うメリットはキーチェーンとかProvisioningやEntitlementを使うAPIのテストが正確にできること、デメリットはアプリが起動することですね。
2:29 AM
forkを使ったテストはデバイス上のテストを諦めるならできます。
Avatar
omochimetaru 1/16/2018 2:29 AM
シミュレーターだといけるってことですか?
Avatar
Kishikawa Katsumi 1/16/2018 2:29 AM
#if simulator (<= まだないけど)にしておけばいい。
Avatar
omochimetaru 1/16/2018 2:29 AM
ほほー
Avatar
Kishikawa Katsumi 1/16/2018 2:30 AM
シミュレータならいけるはず。
2:31 AM
デバイスで子プロセス作れるかちょっと試してみるかな。確か制限されてたと思うんだけど、審査で弾くだけかもしれない。
Avatar
話戻りますが、 actor とエラーの件、↓に書いてありそうです。 https://gist.github.com/lattner/31ed37682ef1576b16bca1432ea9f782#part-3-reliability-through-fault-isolation
Concurrency in Swift: One approach
Avatar
omochimetaru 1/16/2018 2:33 AM
@koher universal error をフックして復帰する機構がないから今のエラー機構のままじゃどうにもならんって
2:33 AM
前読んだ時書いてあったようなきがするけどおぼろげな記憶
2:34 AM
アクターの章は読んだけど「まあそうだよね」って気持ちになった印象がある
Avatar
Part 3 の概要部分だけ読んだけど( Actor Reliability Model まで。それ以降は Part 2 も読まないといけなさそうだし、今は諦めた)、 ! の失敗やオーバーフローにどう対処するかって話をしてるし、それを actor で isolation する話っぽいから、目指してるものとしてはドンピシャのように思うけど、中身はそうじゃないのかな? (edited)
Avatar
#swtws中に失礼します 🙇 viewDidAppear(:) で呼ばれるメソッド等をテストしたい場合って皆さんどうしてますか? let viewController = HogeViewController() window.rootViewController = viewController window.makeKeyAndVisible() let expectation = XCTestExpectation(description: "wait viewDidAppear") DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { XCTContext.runActivity(named: "viewDidAppearでメソッドがコールされた事を確認", block: { (_) in XCTAssertTrue(viewController.calledViewDidAppear) }) expectation.fulfill() } wait(for: [expectation], timeout: 0.2) みたいなコードが乱立するとユニットテストの時間がどんどん長くなるんじゃないかという事を危惧しています。
Avatar
Kishikawa Katsumi 1/20/2018 12:27 PM
トレードオフなので何をテストしたいかによりますね。必要なテストなら時間かかるのも仕方がないですし、他のやり方で構わないのなら実際のビューコントローラを使わないでテストすることも可能だと思います。
Avatar
@Kishikawa Katsumi そうですね。あくまでも上記の例だと呼ばれた事を確認する程度ですが、呼ばれる事が100%分かっている場合は呼ばれるコードを直接テストするとかですかね。有難うございます 🙇
Avatar
window.rootViewController書き換えて ViewController テストする発想が無かった、なるほど、その手があるのか
Avatar
それだと待ち受けるタイミングが難しいの、やったことあるので理解できます
❗ 1
Avatar
テストしたい振る舞いがあるならUIKitから剥がすことしか考えてなかった
Avatar
最終的にはそうなりますね
12:32 PM
もし、VCのライフサイクルとテストが関係ないならば、VCから切り離す方がやりやすいでしょうね
Avatar
確かにそうですねー
Avatar
Kishikawa Katsumi 1/20/2018 12:33 PM
例えばNavigationControllerに入れた時と、そうじゃない時でレイアウトが期待通りになる、みたいなのはViewControllerをテストしないと難しいとかすね。
💡 1
Avatar
むしろレイアウトをテストするっていう概念がなかったかも🤔
Avatar
普通にやるとテストしづらいですからね。目視の方がより多くの欠陥を発見できるという利点もあります。ただ、多くの分岐を持つレイアウト計算は計算部分だけ剥がしてテストしたりしますね
Avatar
そうですね。計算部分のテストはしてます。
Avatar
多くの分岐を持つレイアウト計算
端末増えすぎでもうだめ
Avatar
OSのバージョン分けとかもテスト何回も実行しないといけないとかで面倒ですよね
Avatar
その部分、すごい解決する意欲があるのを思い出しました
👁 1
12:45 PM
ずっと、なんとかならないかなー非効率だなーと思ってたので…
👁 1
👀 2
12:51 PM
これを実現するひとつの手段がシミュレータの多重起動なのですが、3台くらいシミュレータ建ててさらにビルド走らせるとるとカーネルのプロセス数制限あたりにひっかかって厳しいという雑なことも思い出しました
Avatar
あーなるほど
Avatar
コケるのが毎度Carthageのステップなので、なんか変な感じではあるのですが、まだ調べきれてません
Avatar
シミュレータの多重起動自体はこの前のかんもばでもやってる方がいました https://kanmoba.connpass.com/event/70685/
# 開催概要 関西モバイルアプリ研究会(以下関モバ)は、最高のモバイルアプリを作りたいデベロッパーが、お互いに最新の知見を披露して交流する研究会です。 これまでは関西での開催でしたが、この度特別編として東京にて関モバを開催することになりました。ぜひご参加ください。 それぞれの発表は持ち時間5分のライトニングトーク(LT)形式とします。原則として5分以内に、稲妻のような速さと勢いでお話しいただきます。 ## 招待LT 技術書クラウドファンディングPEAKSから発売される「iOS 11 Programming」の著者をお招きして、LTを披露していただきます。当日はできたばかりの製本...
12:57 PM
なので3つで壊れるというのはなんかその状況固有の問題だと思います
Avatar
huinさんだ
Avatar
だいたい3つくらいなんですよね。確かこけてるのが spawn だったかな、そのあたりだったのと、シミュレータの台数を1つ減らすと動くようになるので、プロセス数制限あたりを疑ったというおぼろげな記憶が
1:04 PM
posix_spawn の error code 35 という遺言が残ってました
Avatar
テストではないですが、この前Xcode9で動作確認のためにシミュレーター閉じずに連続でSE、X、8Plus確認し、8を確認しようとRunさせた時、error code 35出ましたね。 その時はシミュレータ1つ閉じたらちゃんとRunで動きましたね (edited)
Avatar
おお、ありがとうございます。被害者の会ができそう…
1:29 PM
前調べた時、35 が EAGAIN で、 posix_spawn(3) のエラーの節から参照されてる fork(2) の EAGAIN の説明にカーネルのプロセス数制限が書いてあって、それで原因がそれだとあたりつけてたのを思い出しました
🤗 1
Avatar
norio_nomura 1/20/2018 1:33 PM
Xcode 9.0 - Simulator - Known Issue https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Chapters/Introduction.html#//apple_ref/doc/uid/TP40001051-CH1-SW1017 When running several simulators simultaneously you may exceed the maximum number of processes or maximum open file limits. If this happens attempts to start new processes or open more files will fail. You can recover by shutting down some simulators or closing open programs. macOS 10.13 automatically scales these limits based on available system memory. On earlier releases these limits are fixed values. These limits can be increased by using launchctl. For more information, choose Help > Simulator Help and navigate to Troubleshoot Simulator > Insufficient resources. (31179087)
👀 1
1:33 PM
これとは別の話なのかな?
Avatar
norio_nomura 1/20/2018 1:42 PM
macOS 10.13より前はプロセス数制限が固定値だから手動で調整が必要、という情報。 (edited)
Avatar
私のposix_spawn error 35が出た環境は、macOS 10.12だったので調整必要ですね。そして調整一切してないですねー…😖 (edited)
Avatar
なるほど、今度試してみます!ありがとうございます
Avatar
Kishikawa Katsumi 1/23/2018 2:58 AM
Swiftプロジェクトで良い感じのアサーションができるソフトウェア、 XCTAssert(xs.contains(4)) | | | | false 4 [1, 2, 3] SwiftPowerAssertがそこそこ安定してきたのでバージョン0.1.0として公開しました。 https://github.com/kishikawakatsumi/SwiftPowerAssert 現時点でもTDDスタイルの開発などにけっこう便利に使えるような気がします。 簡単に試せるようにオンラインのPlaygroundも用意しました。 https://swift-power-assert.kishikawakatsumi.com/ 使ってみてうまく動かないパターンを教えてもらえると嬉しいです。
SwiftPowerAssert - Power Assert in Swift. Provides descriptive assertion messages.
👏 19
Avatar
そういえば、これ面白かったですね https://qiita.com/ukitaka/items/875829ef0e9a5339dfb8
Swiftにおいて、fatalError()preconditionFailure(), Optionalの!try!などで発生したエラー、すなわちSwiftのエラーの分類で言うところの**Universal...
11:00 AM
テスト用途では十分実用的に思います
Avatar
Nimble(が使っているライブラリ)も同じような仕組みでやっているみたいですね https://twitter.com/ikesyo/status/994558554534170624
めっちゃ面白い。ちなみに似たものに https://t.co/0kRsXasHSh というのがあって、NimbleのthrowAssertion()マッチャーに使われています。 / “fatalErrorから復帰させる不思議なS…” https://t.co/yFB...
Avatar
iOS のテスト失敗の原因をわかりやすくするライブラリ MirrorDiffKit の 3.0.0 をリリースしました。CGFloat などを含むオブジェクトについても差分が見られるようになりました: https://t.co/u4gmy8uKMV
👏 5
12:04 PM
Mirror の displayType が nil になるケースを誤解してて、バグってたの直した感じです
12:05 PM
displayType が collection や set になる基準って 前から不思議だったんですが、実は CustomReflectable 使って筋肉でやっているということを最近知りました
Avatar
あと、displayType が nil になる条件も色々調べてたんですが、一つだけわからないことがあって https://github.com/apple/swift/blob/master/stdlib/public/runtime/ReflectionMirror.mm#L510
swift - The Swift Programming Language
12:14 PM
の OpaqueImpl 使ってるクラスって具体的に存在するんでしょうか?
Avatar
そういえば、MirrorDiffKit に Test::Deep でいう supersetof 、RSpec でいう include matcher 相当の機能を入れるかもです https://metacpan.org/pod/Test::Deep#supersetof https://relishapp.com/rspec/rspec-expectations/v/2-0/docs/matchers/include-matcher
Extremely flexible deep comparison
Relish helps your team get the most from Behaviour Driven Development. Publish, browse, search, and organize your Cucumber features on the web.
8:15 AM
struct Example { let a: String let b: String // ... } let example = Example() XCTAssertTrue(example :> (a: "foo", b: "bar")) (edited)
8:15 AM
この例でいう :> を提供する感じですね
8:21 AM
でかい struct とかを検証する際に、別にこの値はどうでもいいんだけどな、というのがよく発生するのですが、それに対する書きやすさと読みやすさの提供が目的ですね
🚀 1
Avatar
I am a developer of a MirrorDiffKit that is a structual diff library. I think MirrorDiffKit is useful for Nimble users on some conditions. So, can Nimble use MirrorDiffKit internally? How do you fe...
1:12 PM
そういえば、Nimble への提案完全にスルーされていた。。。
Avatar
danbo さんが AppCode の Unit Test Bundle で XCTContext 動かない問題報告してくれたのに、動きがなくて悲しい
😢 1
Avatar
実は、「iOS テストライブコーディング道場」という勉強会をやろうとかモヤモヤ考えています。みんなでテストできないコードを持ち寄って、識者数人で喋りながらテストをライブコーディングするというものです。
前にお話ししたこの話、開催の機運が出てきました
👍 8
Avatar
時期感としては 10月〜11月、場所はおそらく渋谷の某高いビルになりそうな気配
11:39 AM
あ、それと、このテスト道場企画とは直接関係ないんですが、TDD Boot Camp が 9 月に開催されます。私はここで Swift 担当の Teaching Assistant として出る予定なので、もし Swift や iOS で TDD 体験してみたい!という方はぜひ。 https://tddbc.connpass.com/event/98444/ (edited)
# はじめに TDD Boot Camp(TDDBC) とは、テスト駆動開発(Test Driven Development)について、座学だけでなく、実習形式で手を動かして体得することを目的とするイベントです。 # 基調講演者紹介 テスト駆動開発およ...
😊 1
Avatar
しばらく放置していたらkuniwakさんが面白い話を流していそうだった👀
Avatar
TDDBC、Swiftで参加します。よろしくお願いします!
swift 2
Avatar
花芽尋かすみ 8/21/2018 2:18 PM
AppCodeでXCTContextがうまく動かないissueがマージされたっぽい🎉 https://youtrack.jetbrains.com/issue/OC-17586
😍 2
Avatar
いやー、よかったです
🙏 1
Avatar
@here TDDBC の Swift 担当の TA が 1 名ほど足らないのですが、どなたか興味ある方いますか?(今のままだと 8 人を私一人で見ることになってしまう) TDDBC は参加者でペアプロしてもらい、TA がアドバイスするという形式になっていて、TA 側に必要な知識は、(1) XCTest/Quick の動かし方、(2) テストのレポートの読み方、(3) ビルド設定が間違った時や設定が壊れた時の直し方、(4) TDD の経験ぐらいだと思います。
7:56 AM
日時は 2018/09/29 10:00〜 で、場所は東京です
Avatar
daisukeokaoss 8/27/2018 8:00 AM
イベント情報晒せますかね?
Avatar
# はじめに TDD Boot Camp(TDDBC) とは、テスト駆動開発(Test Driven Development)について、座学だけでなく、実習形式で手を動かして体得することを目的とするイベントです。 # 基調講演者紹介 テスト駆動開発およ...
8:00 AM
これです
8:00 AM
今のところ TA は別枠で参加登録してるので、もしご興味あればお声がけいただけると Slack へご招待します
Avatar
daisukeokaoss 8/27/2018 8:02 AM
教えるほど知識ないんですよね、「発想生成2」という野良アプリ作ったぐらいっで
8:02 AM
daisukeokaoss has 52 repositories available. Follow their code on GitHub.
Avatar
Hassouseisei_ver_3_0 - 「発想生成」のSwift版です
Avatar
daisukeokaoss 8/27/2018 8:03 AM
そうですね
8:03 AM
アプリストアにアップしてあります、むしろ教えて欲しい
Avatar
ww
8:03 AM
今は参加枠埋まってますが、もしかしたら増員されるかもしれないので、ウォッチしておくといいかもです (edited)
Avatar
daisukeokaoss 8/27/2018 8:04 AM
そうですね、でも基本、教えるとなるとプレッシャーかかるんですよね。他の人に関しては知らないです
Avatar
わかります、なのであまり軽率に大丈夫!とかは言えないですね
Avatar
daisukeokaoss 8/27/2018 8:05 AM
そうなんですよね。
Avatar
ちなみに、教わる側の参加者は半分くらいは入門TDDの前半を読んできていて3割が読破、2割くらいが未読な感じで、それぐらいの温度感だと思っていただければ。
Avatar
daisukeokaoss 8/27/2018 8:07 AM
やばい、ガチじゃないですか
Avatar
なお、過去の経験では、優秀なペアには TA がほぼいらないという感じもあります
Avatar
daisukeokaoss 8/27/2018 8:09 AM
多分、優秀な人を強制的にTAにしたほうがいい気がします
Avatar
www
8:10 AM
(わかる)
Avatar
daisukeokaoss 8/27/2018 8:11 AM
「他のスタッフの指示に従わない」が退出の条件なら、可能ですよねwwwwwwww
😇 1
Avatar
開発時間に占めるデバッグ時間の割合は少なくないため、この時間の短縮は開発速度を上げるためにとても重要です。この発表では、実際の中規模なアプリ開発で70%増もの開発速度向上を支えたデバッグノ...
9:24 AM
デバッグといいつつ、実際はテストの発表という変則的なスライドです
Avatar
@kuniorock iOSDC現場にいませんでしたが、スライドがとても興味深くスライドから来ました。勉強させていただきますtdd テストファースト勉強中の身ですよろしくお願いします(; ・`д・´)
Avatar
おお!こちらこそよろしくお願いしますー
Avatar
テストの発表が iOSDC で二位になって嬉しい限りですねー 😆 がんがんテストの CfP 通るようになってほしい
🙌 6
👍 1
Avatar
iOSDC Japan 2018 で、ベストトーク賞2位をいただきました。タイトルは「iOSアプリの開発速度を170%に向上させたデバッグノウハウ」です。この記事では、スライドの紹介に加えて、スライドに書ききれなかっ...
2:53 AM
蛇足書きました
Avatar
omochimetaru 9/3/2018 2:54 AM
口頭でも直接言ったけど、ここが本当に感心しました。
しかし、私はこの発表でなるべく「テスト」というキーワードの使用を避けました。
🙏 1
2:56 AM
質疑応答の「テストする時間の確保をどうやって認めてもらえばよいのか?」 に対して、「それで加速する分でお釣りが出るから勝手にやればよろしい」 ってくだりも良かったですねえ
2:57 AM
その説得のために冒頭の手戻りの話なんかを、テスト関係ないデバッグノウハウの話として持ってきているので
2:57 AM
本質的な説明だなあとおもった
Avatar
ありがとうございます、恐縮です。実際のところ、開発者自身によるテストって開発速度の高速化が最大の関心ごとなんですよね。そのあたりをうまく説明していて、かつ iOS 向けの資料ってほとんどないんです
3:00 AM
あと、テスト勝手に書くの話は Ask the speaker で続きがあったんです。というのも、質問者の悩みは「新規コードではなく高齢なコードに単体テスト導入と設計改善を取り組もうとしているのだけれど、この時間をどうとったらいいだろうか」だったようで、そこのフォローをしてました
Avatar
omochimetaru 9/3/2018 3:01 AM
テストに詳しい人達の中ではそのあたり(時間短縮)はもう前提になっちゃっていて、 テストに詳しくない人たちとギャップがありそうですよね
3:02 AM
ああ〜なるほど>つづき
Avatar
私の回答は「経営層に話を聞いて、経営課題とリファクタリングを結びつけるのがいい。例えば、新規施策を高速に施行できるようになってほしいという経営的な要望があるのならば、今はそうなってないからそれを準備するための時間をください、と説明すると納得してもらいやすい。また、経営課題がコロコロ変わって設計が振り回されるケースでは、経営課題が安定しないので、どんな経営課題でもそれなりの成果を出せるような状態にする時間をください、が通りやすいと思う」といった感じです
🙂 5
✍ 11
Avatar
明日の iOSDC Reject Conference days 2 でテストのライブコーディングします
7:41 AM
days 1 の danbo さんは TDD で新規コードをやっていく感じだったので、私の方は既存コードを解体していく流れを予定してます
👏 3
12:35 PM
そして動画です
Avatar
花芽尋かすみ 10/1/2018 2:03 AM
TDDBC SendaiでSwiftのTAやってきます。仙台以外の方も歓迎です!💪 https://tddbc.connpass.com/event/99555 (edited)
# はじめに TDD Boot Camp(TDDBC) とは、テスト駆動開発(Test Driven Development)について、座学だけでなく、実習形式で手を動かして体得することを目的とするイベントです。 ## 更新情報 * 2018/8/29 イベントを公開...
👏 2
Avatar
流石に勉強会ラッシュで疲れたので今回はお休みします…!
👍 1
Avatar
Xcode10でAccessibility Inspectorがうまく動かなくて、webviewの要素が取れずにテストが落ちるのですが、同じ状況の方いますか?
🙅 1
Avatar
Mutation testing system built on top of LLVM. Contribute to mull-project/mull development by creating an account on GitHub.
Avatar
LLVM レイヤーでの mutation testing だと、SIL レイヤーでの型情報失われてるので意味のない mutation (本来ならビルドできない mutation)もありえそう… (edited)
9:44 AM
やはり Swift 用の mutation testing framework がほしいですね
Avatar
mutation testingを知らないんですが、このREADMEのスクショの、コメント文で書いてある式が検査されるんですか?
Avatar
えと、このスクショが何を意味してるのかは微妙ですね
9:46 AM
mutation testing は、テスト対象のコードに意図的にバグを埋め込み、それに対してテストを実行する検査手法ですね。なので、基本的にはテストコードの品質がわかるような類の手法です
9:46 AM
例えば、 a > ba < b とかに書き換えたときに、ちゃんとテストが検知できるか、みたいなのを検査するイメージです (edited)
Avatar
なるほど、コードをランダムに壊すのか。
Avatar
もし検知できなければテストが足らないことを示唆していて、複数のテストが一斉に検知してしまった場合は、テストの独立性がないことを示唆しています
9:49 AM
なので、それぞれのバグ埋め込みに対して、それぞれ1つのテストが落ちるのが理想的な形になります (edited)
9:55 AM
↑ここにこのツールの仕組みの擬似コードが書いてありました
9:56 AM
テスト対象のコードをLLVM Moduleとして編集して再ロードさせることで
9:56 AM
元の言語のレベルでリコンパイルすることなく
9:56 AM
テスト対象のバイナリだけをJITで差し替えつつmutation testを回す・・・っぽい。
Avatar
おー、なるほど、JIT で差し替えるのはいいですね
10:36 AM
Mutation testing の最大の欠点が遅いことなんですが、確かに JIT で差し替えれば rebuild とかの必要ないから素早い
Avatar
いろいろ変な事にならないのかは気になるけど、型が壊れない範囲でBasicBlockの中のinstructionを差し替えてるだけだから、うまく動くって感じですかねえ
Avatar
型が壊れないのは LLVM レベルの話だと思うので、Swift の型検査には通らないみたいなケースは結構ありそうな気がします
Avatar
Supported mutation operators Math: Add,Sub,Mul,Div: replaces + with -, - with +, * with /, / with *. Negate Condition: inverses conditions like A -> !A or == -> !=. Remove Void Function Call: removes a function which doesn't have a return value. Replace Call: replaces function calls with Int, Float and Double return values with number 42. Alpha state, not enabled by default. Scalar Value: replaces 0 with 1, other numbers with 0. Alpha state, not enabled by default. AND <-> OR: replaces && -> || and vice versa. Alpha state, not enabled by default.
10:38 AM
リストがあった。
Avatar
これは結構な mutator をサポートしてる感じですね
10:38 AM
少なくとも私の知っているものは全て入ってました
Avatar
ほ〜
10:39 AM
他の言語だとこの辺りがありますね
10:40 AM
Mutation testing for JavaScript and friends. Contribute to stryker-mutator/stryker development by creating an account on GitHub.
10:40 AM
Mutation testing for JavaScript and friends. Contribute to stryker-mutator/stryker development by creating an account on GitHub.
Avatar
なるほど〜
Avatar
本当は追加するのも試してほしいんですが、そうすると無条件で init できるようにする protocol への準拠が必要そうだったりして難しそう
Avatar
🍤ACエビフライ🔌 10/31/2018 8:51 AM
テストコードで、テストに関係ない関数はスタブに指定せずに済ませたいので、最近は以下のようなスタブを書いたりしています。 しかし、コードの重複(groupとか作るの)が地味に面倒です。 ```Swift func group(id: Int) -> Observable<Group> { return _group(id) } private var _group: ( id: Int) -> Observable<Group> init( group: @escaping (( id: Int) -> Observable<Group>) = { _ in Observable.never() } ) { _group = group } ``` みなさんどうされてますか? 考えたこと:
  • そもそもこんな汎用的なスタブがおかしい ←ありうる
  • classにして必要なものだけoverride ← structではできない
  • コード生成 ←使ったことがないのでコスパ感がよくわからない
  • 現状で我慢 ← 🤔
(edited)
8:54 AM
理想では func group: (id: Int) -> Observable<Group> init( group: @escaping ((_ id: Int) -> Observable<Group>) = { _ in Observable.never() } ) { self.group = group } とかやれたら最高なんですけど (edited)
Avatar
既存のクラスのスタブ版を作りたいけど、 挙動全部をスタブ化する必要がないから、 既存のクラスの実装の一部だけをスタブ実装に差し替えたくて、 現状だと内部に関数型のプロパティを置いて、 メソッドの実装をそれの呼び出しにすることで挙動の切り替えを実現している(例では_group)、 という話ですか? (edited)
Avatar
🍤ACエビフライ🔌 10/31/2018 9:21 AM
わかりづらくてすみません 既存のclassやstructのスタブ版を作りたい場合もありますし、 そもそも実装がまだなくてインターフェースだけprotocolで決めてあるときとかもです。 たとえば class Dog : Animal がまだなくて、 protocol Animal はすでに↓みたいなのがあって protocol Animal { func group(id: Int) -> Observable<Group> func bark() -> String } まずはAnimalを使ったモジュールのテストを書いていこうというとき、現状では↓のような汎用のスタブを作り struct StubAnimal { func group(id: Int) -> Observable<Group> { return _group(id) } private var group: ( id: Int) -> Observable<Group> func bark() -> String { return _bark() } private var _bark: () -> String init( group: @escaping ((_ id: Int) -> Observable<Group>) = { _ in Observable.never() } , bark: @escaping (() -> String) = { _ in "meow" } ) { _group = group _bark = bark } } SUTに関係ない関数はデフォルト引数で済ませられるよう、また、何に関心を持っているか、何がSUTへの間接入力になりうるかが明確になるようにしています。 (edited)
Avatar
group と bark はそんなに内容が変わりうるような感じです?
Avatar
よくわかってないですけどtest moduleにprotocol extension置いたら他の型に全部実装しなくてよくなりそうですかね?
Avatar
というのもなぜ closure なんだろうと
Avatar
StubAnimal.initにわたすクロージャが、テストケースごとに変化するってことですかね
Avatar
それ自体はあまり良くないプラクティスな気がしますね
Avatar
🍤ACエビフライ🔌 10/31/2018 1:57 PM
@Kuniwak closureにしたのは、あるfuncが呼ばれたらObservableの値が変わるというような挙動を再現したかったからです。 そこに揃えていった結果、それ以外のfuncもclosureになってきました。 @t.ae#5802 たしかにTestモジュールにデフォルト実装を置いておいて、各テストごとに必要なところだけ実装を追加するとやりたいことができるような気がしてきました。ちょっとやってみます。 @omochimetaru そうです。initにわたすクロージャをテストケースごとに変化させて、Stubをたくさん作らなくても挙動をカスタマイズできるようにしたいなと思ってまして。
🤔 1
Avatar
omochimetaru 11/2/2018 1:30 AM
@🍤ACエビフライ🔌 テストする対象の状態変更は、それ自体がもつメソッドによってなされるのが基本で、 テスト対象の挙動をテストケースごとに実装してしまうと、 テストとして良くないような気がします。 でも、StubAnimalをテストしたいわけじゃなくて、 StubAnimalとやり取りするなにか別のオブジェクトをテストしたくて、 その影響を制御するためなら、こういうこともあるかなあと思います (edited)
1:31 AM
ネットワーク系のライブラリのテストケースではそういうのを見たことがあります。 通信先からどんなデータが飛んでくるか、ということが、 何でも起こりうるから、そうするしかない。 RxSwiftのテストコードとかも、流れてくるストリームをテストケースごとに構築してます。 そういう外部環境の表現としてStubAnimalがあるなら、妥当だと思います (edited)
1:33 AM
スタブだし、そういう話なのかな。
Avatar
🍤ACエビフライ🔌 11/2/2018 12:15 PM
@omochimetaru テスト対象の実装はテストケースでは変化させていません。StubAnimalはSUTをテストするための外部環境として使っています @t.ae#5802 さんのアドバイスをうけてTest module内にextensionでデフォルト実装を定義し、Stubではそのテストで関心がある間接入力だけを定義する方法で書き直してみたところ、以前よりかなり見通しのいいテストになりました 以前のStubはStubと名乗りながら、間接出力をチェックしたり間接出力のタイミングに依存して間接入力を返したり、Dummyとしても振る舞えるようにしていて、それが根本的な問題だったように思います。 書き直したタイミングでStubは間接入力にほぼ専念するようにしたので、かなり綺麗になりました。
Avatar
🍤ACエビフライ🔌 11/2/2018 12:43 PM
Rxまわりのテストは↓これを参考に書いていこうとおもってます https://speakerdeck.com/takehilo/rxtest-rxblocking-test-patterns
iOSDC 2018 Reject Conferenceで行ったトークのスライドです。 RxTest、RxBlockingというライブラリの概要と、これらを使ったRxなコードのテストの基本的な書き方を、ViewModelとAPIクライアントという2つのクラスを題材...
Avatar
🍤ACエビフライ🔌 11/30/2018 6:56 AM
HTTP(multipart/form-data)によるアップロードをするAPIのテストを書きたいのですが、どのようにするとよいでしょうか。good practiceをご存知だったら教えていただきたいです。 (いまMockingjayをつかってbuilderでURLRequestを受け取って.httpBody や .httpBodyStream を見ようとしていますがうまくいっていないです)
Avatar
Kishikawa Katsumi 11/30/2018 7:08 AM
テストしたいのはどこですか?Multipartの組み立てがちゃんとできてるか?ですか?
Avatar
汎用HTTPサーバーフレームワークです。HTTPサーバが簡単に作れます。
7:09 AM
↑僕はコレでMacでちょろっとサーバー立てて、
7:09 AM
ファイル受け取って画像デコードしてサイズ見て、みたいなのをテストしたりしました。
Avatar
🍤ACエビフライ🔌 11/30/2018 7:14 AM
@Kishikawa Katsumi テストしたいのは想定通りのMultipartを投げているかどうかです。
Avatar
Kishikawa Katsumi 11/30/2018 7:15 AM
ならサーバのモックとかは使わずに、リクエストを組み立てているロジックを関数に独立させてテストするのが良いです。
7:17 AM
与えたInput(ファイルやバイト配列など)から、Boundaryを挟んでちゃんと合法なリクエストボディになってるかどうかということなので。モックを使ってとかはどうしても関数にできないからしょうがなくブラックボックステストでやるしかない、場合は必要ですが、そうでなければもっと簡単にやる方がいいです。
7:18 AM
実際にサーバがそれを受け取れるかという観点のテストがさらに必要な場合は分けてそれだけをやります。
7:19 AM
Practiceというなら、モックなどを使って全部いっぺんにやろうとしない、小さい単位に分けてテストして個々があってるなら全体も正しい、という風にするのがGood Practiceです。
Avatar
🍤ACエビフライ🔌 11/30/2018 7:29 AM
@Kishikawa Katsumi マルチパートの組み立ては、Alamofireに設定クロージャを渡すと、Alamofireがそのクロージャを実行してAlamofire.MultipartFormDataインスタンスの設定が行われ、そのMultipartFormDataが実際の組み立てをやるようになっています。 今みつけたのですが AlamofireのMultipartFormData.encode() -> Data で組み立て後のDataを取得できそうです。 設定用クロージャを切り出して、MultipartFormData.encode() の戻り値を検証する形でテスト書けそうなのでやってみます。 ありがとうございます。
Avatar
Kishikawa Katsumi 11/30/2018 7:31 AM
Alamofire使ってるならAlamofireの方でテストされてるので https://github.com/Alamofire/Alamofire/blob/d0208adc369b3fb1e622aca5f0a3e0d170c4832b/Tests/MultipartFormDataTests.swift やらないという選択もありです。
Elegant HTTP Networking in Swift. Contribute to Alamofire/Alamofire development by creating an account on GitHub.
Avatar
🍤ACエビフライ🔌 11/30/2018 7:31 AM
@omochimetaru ありがとうございます。 粒度の小さなテストがかけそうになってきたのでそちらを試してみます。
😄 1
Avatar
🍤ACエビフライ🔌 11/30/2018 7:40 AM
@Kishikawa Katsumi Alamofire.MultipartFormDataが正しいmultipart/form-dataを吐くことはそちらのテストにまかせたいです。 我々のテストではAlamofire.MultipartFormDataに対して設定をかけている我々のコードが正しいことをチェックしたいです。
7:41 AM
MultipartFormDataのSpyをつくってそこへの間接出力を検証するほうがいいでしょうか?
Avatar
Kishikawa Katsumi 11/30/2018 7:45 AM
簡単にできるならそれでいいと思いますけど、MultipartFormDataを作るところってそんなに間違えるようなところはなさそうに見えるのでそこまでやらなくて良いように思います。 もう少し具体的にどういう使い方をしていて、どんな間違いを防ぎたい、みたいなの見せてもらえませんか?
Avatar
🍤ACエビフライ🔌 11/30/2018 8:16 AM
@Kishikawa Katsumi 我々のAPIは基本的にJSONでサーバとやりとりしているのですが、ユーザの画像と一緒に名前や自己紹介文を更新するAPIがあって、これだけmultipartでアップロードする仕様になっています。(なぜこうなっているかは不明です) 想定される間違いとしてはパートの名前が間違っているとか、mimeタイプの指定を忘れたとかの軽度なミスです。 テストのモチベーションとしては、いま想定できる軽度なミスよりも、このAPIだけmultipart/form-dataなので不安が大きいこと、サーバサイドには一切テストがなく、iOSサイドのテストで入出力の仕様を記述しておきたいということのほうが大きいです。 (edited)
Avatar
Kishikawa Katsumi 11/30/2018 8:18 AM
それなら手間でもモックなりなんなりを使ってやるというのは理解できます。
8:19 AM
なぜこうなっているかは不明です
まあJSONにバイトデータが載らないからだと思います。 Base64等でテキストにするという手はよくありますが、それはそれでサイズが増えるとかデメリットもありますし。
Avatar
JSONに画像入らないから、画像まるごとPostBodyでアップロードするAPIを別で用意したい派
Avatar
Kishikawa Katsumi 11/30/2018 8:38 AM
それはそれで片方だけ失敗したらどうする問題があるので悩ましいですね。Instagramのようなサービスなら絶対そっちがいいですけど。
Avatar
サーバー側で宙ぶらりんになってる画像をGCする仕組みが必要ですね。
Avatar
🍤ACエビフライ🔌 11/30/2018 8:50 AM
@Kishikawa Katsumi なるほど画像だからってのと同時更新ってのがキモかもしれません。更新だけでなく新規アカウント作成時にも使っているAPIなので。
8:54 AM
@Kishikawa Katsumi @omochimetaru とりあえずMultipartFormData.encode()の出力を検証しておいて、あとは進捗と相談しながらやってみたいとおもいます。
Avatar
🍤ACエビフライ🔌 11/30/2018 12:08 PM
結局 MultipartFormData にextensionをはやして、そこに対するテストを書くって形にしたらなんとなく全体的にいい感じで安心感もでてきたので、とりあえずこれで行こうとおもっています。
Avatar
Test初心者から質問させていただきます、ProtocolをMockする時Protocol中で他のframeworkのタイプに依存しないほうがいい?
Avatar
Kishikawa Katsumi 4/5/2019 3:41 AM
一般論でいうと依存はないほうがいいです。 あとはテストする対象とか変更のコストがどうかとか具体的な内容によって変わります。 やろうとしてるところのコードを未完成でもいいので見せてもらったほうがいいですね。
👍 1
Avatar
返答ありがとうございます。いまVIPERのパーツをテストする際に自動生成したMockクラスが他のライブラリーのタイプに依存してしまうことが発生しました、一旦依存を外してやってみます。🙏
Avatar
Kishikawa Katsumi 4/5/2019 4:18 AM
もう少し突っ込んだ一般論をいうと、 モックにする目的は、テストしたいもの以外で失敗するケースを除きたい、あるいはテストしたいものをテストできる状態に持っていくコストが高い・難しい、という問題を解決するためなので、 テスト対象がそもそもそれに依存しているのは当然、みたいなものは依存を外すのは却って大変になるので依存させていいです。 要はモックにすることでテストが簡単になるとか、別の要因で失敗しなくなる、というメリットがあるかどうかが重要。
👍 4
Avatar
テスト関しる説明してくれてありがとうございます。その辺の知識をちゃんと勉強して行きます。💪
Avatar
func testX() { let x: Float80 = 0 XCTAssertEqual(x, 0) // OK XCTAssertEqual(x, 0, accuracy: 1e-4) // EXC_BAD_INSTRUCTION } XCTestこれだけでクラッシュしててひどい
3:29 AM
https://developer.apple.com/bug-reporting/ 403で見れないんですけど僕だけでしょうか?
Avatar
omochimetaru 6/27/2019 3:30 AM
そのURLは開けた。
Avatar
このさきです。
3:30 AM
feedback assistant
Avatar
omochimetaru 6/27/2019 3:30 AM
403だ。
3:31 AM
Float80とaccuracyの組み合わせで落ちるの?
Avatar
みたいですね。
Avatar
omochimetaru 6/27/2019 3:31 AM
やばw
Avatar
norio_nomura 6/27/2019 4:05 AM
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
Avatar
omochimetaru 6/27/2019 4:05 AM
おお。こんなふうになってるのか。
Avatar
これswiftリポジトリにあったんですね……
5:26 AM
単にFloat80が実装されていないだけ?
Avatar
omochimetaru 6/27/2019 5:27 AM
これ関数名ぶつかってないのかな
5:27 AM
_XCTPreformattedFailureHandlerは外からくるっぽいけど
5:28 AM
全部コード見えてるしFloat80も実装可能に見えるね
Avatar
自前実装はできそうですね。
Avatar
omochimetaru 6/27/2019 5:29 AM
PRだしてみたら?
Avatar
そうですね。やってみます。
5:36 AM
しかし個別実装になっててこのままでいいのかという気持ちは無くもないですね。 将来的にApproximate Equalityで不要になりそうですけど。 https://github.com/apple/swift-evolution/blob/master/proposals/0259-approximately-equal.md
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - apple/swift-evolution
Avatar
omochimetaru 6/27/2019 5:37 AM
無限大とか変な値に関しても同じ挙動になるかな
Avatar
微妙な仕様の差異は有り得そうですねぇ
Avatar
omochimetaru 6/27/2019 5:38 AM
テストフレームワークだから微妙な差はよくなさそう
Avatar
norio_nomura 7/15/2019 4:49 AM
expectCrashが欲しい…
Avatar
norio_nomura 7/15/2019 1:41 PM
/// Asserts that an expression crashes. /// - Important: **The expression will not be evaluated if current process is being debugged.** /// - Parameters: /// - expression: An `expression` that can crash. /// - message: An optional description of the failure. /// - file: The file in which failure occurred. /// Defaults to the file name of the test case in which this function was called. /// - line: The line number on which failure occurred. /// Defaults to the line number on which this function was called. /// - signalHandler: An optional handler for signal that are produced by `expression`. /// - stdoutHandler: An optional handler for stdout that are produced by `expression`. /// - stderrHandler: An optional handler for stderr that are produced by `expression`. /// - Returns: A value of type `T?`, the result of evaluating the given `expression`. /// `nil` if expression crashed. @discardableResult public func XCTAssertCrash<T>( _ expression: @escaping @autoclosure () -> T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line, signalHandler: (Int32) -> Void = { _ in }, stdoutHandler: (String) -> Void = { _ in }, stderrHandler: (String) -> Void = { _ in } ) -> T? (edited)
Avatar
norio_nomura 7/15/2019 3:47 PM
XCTAssertCrashesの方が良いだろうか。
Avatar
norio_nomura 7/16/2019 7:10 AM
A Matcher Framework for Swift and Objective-C. Contribute to Quick/Nimble development by creating an account on GitHub.
Avatar
omochimetaru 7/16/2019 7:12 AM
欲しい気持ちはわかるけど、クラッシュはそこから制御が戻せない以上、無理そう
7:13 AM
Fortifyみたいな裏技もあるけど、言語規格上いろいろな中間状態の安全性を保証できないし、テスト実行系の制御の再開ができない
Avatar
norio_nomura 7/16/2019 7:15 AM
実行時の動作継続とかではなく、ライブラリの挙動の互換性確認的な用途です。
7:16 AM
パラメータにnegative Intを渡すとfatalErrorになる挙動も真似したいとか。
Avatar
ukitaka先輩のこれが使えそう。 https://github.com/ukitaka/XCTAssertUnrecoverable
Make it possible to test that universal error / logic failure occurs. - ukitaka/XCTAssertUnrecoverable
7:17 AM
中身はFortifyですね
Avatar
norio_nomura 7/16/2019 7:17 AM
あ、手元ではもう自分の実用になるものがほぼ出来てます。
Avatar
なるほど
Avatar
norio_nomura 7/16/2019 7:17 AM
作る過程で色々わかった制限を、先行事例がどの様に回避している(出来てる?)とかが気になったのです。
7:20 AM
Nimbleは、僕が避けたMach exceptionsの仕組みを使うライブラリを利用してXcodeのlldbと共存出来てるのすごい。 https://github.com/mattgallagher/CwlPreconditionTesting (edited)
A Mach exception handler that allows Swift precondition failures to be caught and tested. - mattgallagher/CwlPreconditionTesting
7:27 AM
ukitakaさんのXCTAssertUnrecoverablesigactionが内部で使われてるから、僕のと同じ制限があるな。
Avatar
omochimetaru 7/16/2019 7:50 AM
autoclosureで式を包んでて、実行はその式の評価前に戻ってるのか。
Avatar
norio_nomura 7/16/2019 7:55 AM
僕はsetjump, longjumpを使わずに、別Threadでクロージャを実行して、trap有無を確認してからThread.exit()な感じにした。
Avatar
omochimetaru 7/16/2019 7:56 AM
実行時の動作継続とかではなく、ライブラリの挙動の互換性確認的な用途です。
7:56 AM
これの意味によると思うんですけど、 「fatalErrorが一切発生しない」ことをテストしていて、「発生したら壊れてる」を検知したいならいいと思うんですが (edited)
7:57 AM
パラメータにnegative Intを渡すとfatalErrorになる挙動も真似したいとか。
7:57 AM
これがあるってことは、fatalErrorが発生したあとも、テストが継続実行されることを想定しているはずで
7:57 AM
でも、その状態で想定外の副作用が発生してないことが保証できないと思うんですよね
7:58 AM
例えば、シグナルが発生した後に本来は(エラーが無ければ)あるはずのスコープexitの処理が実行されないので、
7:58 AM
あるグローバル変数を、defer文を使って、スコープを抜ける時にnilにする、みたいなロジックがあった場合、
Avatar
norio_nomura 7/16/2019 7:58 AM
SwiftPMの場合、--parallelを使うと全部別プロセスになるから、問題なくなる。 (edited)
Avatar
omochimetaru 7/16/2019 7:59 AM
正しくfatalErrorが発生しました、ってテストケースはキャッチするけど、そのグローバル変数への副作用は期待してないものになりうる。
7:59 AM
あるクラスの内部で、Klass.shared みたいなシングルトンを使ってる場合も、そういう感じで変な途中状態が残っちゃう可能性があります
8:00 AM
あと、スコープexitがちゃんとされないってことは、参照型はリークすると思うし。
Avatar
使える用途としては、Sharedな環境を汚さないものだけじゃないかな、当然だけどそういうのは用途を制限すると思います。
Avatar
omochimetaru 7/16/2019 8:01 AM
まあだいたいは厄介なことは起きないと思うけど、なんらかの条件の組み合わせで踏み抜いたとき、めちゃくちゃハマると思うんですよね
8:02 AM
で、そういうものはユーザライブラリでやる分にはいいけど、XCTestそれ自体とかに公式採用するのは良くないと思う。
Avatar
norio_nomura 7/16/2019 8:02 AM
まあ、XCTest本体に欲しいとは思っていません。 (edited)
8:08 AM
別Threadでクロージャを実行して、trap有無を確認してからThread.exit()な感じにした。
他スレッドへの影響を最低限にする、という意味ではThread.exit()しない方が良いかも。
Avatar
norio_nomura 7/16/2019 8:22 AM
パラレルテストで動いていることが確認できない場合は、クラッシュテストを走らせない仕組みは入れる。
Avatar
omochimetaru 7/16/2019 8:23 AM
setjumpよりはスレッド切ったほうがいろいろとマシそうな気はします
Avatar
norio_nomura 7/16/2019 8:24 AM
Xcodeから実行されてる時に、パラレルテストが有効かどうかの判定基準がなさげ…
8:26 AM
その場合はクラッシュテストを走らせないから、まあ良さげ。
8:27 AM
macOS, iOS, tvOS, Linuxで動作。
Avatar
norio_nomura 7/16/2019 8:48 AM
XCTAssertCrash()を作ったとして、XCTAssertNoCrash()は必要なのか? (edited)
Avatar
普通にそのまま実行できたらNoCrashなので、本質的には必要ない…?
9:40 AM
もしくはここでクラッシュしても次には進めて欲しいから、NoCrashで発生したクラッシュを吸収してXCTFailに変換したいとか…?
🤔 1
Avatar
とりあえずXCTAssertNoCrash()は不要ぽい。
Avatar
norio_nomura 7/18/2019 1:18 AM
API ChangesをCIでチェックする仕組みをSwiftNIOが取り入れたらしい。 https://twitter.com/johannesweiss/status/1151390949320384512 (edited)
#SwiftNIO now has automated public API breakage checking. Thanks @tomerdoron for integrating this & @xge_apple and team for making the awesome swift-api-digester. #SwiftNIOgrowingup The script to check API breakages should work for any SwiftPM project btw: https://t.co/kmf...
😲 1
1:18 AM
パブリックAPIに変更があった場合、CIが失敗する例。 https://github.com/apple/swift-nio/pull/1072 (edited)
deliberately breaking the public API to see if the tooling works.
1:20 AM
Event-driven network application framework for high performance protocol servers & clients, non-blocking. - apple/swift-nio
Avatar
norio_nomura 7/18/2019 1:27 AM
これ、APIの変更を受け入れる時はどういうフローになるのだろう…
Avatar
omochimetaru 7/18/2019 7:09 AM
swift api-digester -sdk "$sdk" -diagnose-sdk \ --input-paths "$tmpdir/api-old/$f" -input-paths "$tmpdir/api-new/$f" 2>&1 \ > "$report" 2>&1
7:09 AM
不思議な引数ですね・・・
7:09 AM
ハイフン2個と1個で指定を分けるって。
Avatar
norio_nomura 7/19/2019 9:47 AM
オレオレXCTAssertCrash()をMac Exception仕様への書き換えがほぼ終わったので、iOSデバイス上のテストでどうなるか確認してみた。
9:49 AM
assert系は実機だと全部ブレークポイントになってるから、デバッガで設定するブレークポイントと区別をつけるのが無理かも? (edited)
9:50 AM
bad access系は拾えそうだけど、僕が欲しい「仕様としてのクラッシュ」ではないから、対応しても意味なさげ。
Avatar
norio_nomura 7/21/2019 8:58 AM
ようやくGitHubへpushした。 https://github.com/norio-nomura/XCTAssertCrash
Asserts that an expression crashes by using Mach Exception Handler or POSIX Signal Handler. - norio-nomura/XCTAssertCrash
9:00 AM
assert系は実機だと全部ブレークポイントになってるから、デバッガで設定するブレークポイントと区別をつけるのが無理かも?
区別は出来るけど、評価するexpression中にXcodeで設定するブレークポイントとは共存出来なかった。
(edited)
Avatar
@tarunon XCTAssertNoLeakって、シングルトンを所持しているプロパティに対してLeakを検出してしまうのに対処する方法ってありますか?
Avatar
検知しないように設定できますよ
8:04 AM
えーと
Avatar
CustomTraversable それっぽいものが!
Avatar
Provides assert function that check memory leak in Swift. - tarunon/XCTAssertNoLeak
Avatar
おお〜できました。ありがとうございます!!
Avatar
XCTUnwrapってまだSwiftPMから使えないんですね。 (edited)
Avatar
XCTUnwrap、これで実装されてるのでSwift 5.1から使えそうなんですけど使えないのかな https://github.com/apple/swift-corelibs-xctest/pull/279
Adds a new API XCTUnwrap which asserts that an expression is non-nil, and returns the unwrapped value. This matches a new API added in Apple&#39;s ObjC XCTest framework in Xcode 11 Beta 1 (see ...
12:39 PM
SwiftPMでというかcorelibs-xctestなのでLinuxでの話ですけど。
12:39 PM
macOSでのSwiftPMでも使えないのかな
Avatar
Quick/Nimble で async な API をテストするときのベストプラクティス的な方法ってありますか?↓ここに書かれている extensionhttps://github.com/Quick/Quick/issues/1084#issuecomment-1007665281 (edited)
Just like it was added in XCTest, it would be great to be able to do this: it("") { expect(await f()) == 1 }
Avatar
おっ nsoto
Avatar
ご無沙汰しております。Kuniwak です。今週金曜日10/28の夜に iOS アプリのテストのオンライン勉強会 iOS Test Online をやります。 発表内容はこんな感じです: kuniwak: 「実践 9つのメモリリークどう見つける?」 uhooi: 「新規アプリの単体テスト戦略」 treastrain: 「Bitrise Pipelines に移行して、クレジットを節約しながら並列でビルド・テストを回す」 パネルディスカッション(20分):「シフトレフトがいいってほんと?」 まだ参加枠がありますので、ご興味がありましたらぜひご参加ください! https://testonline.connpass.com/event/261910/
2022/10/13 更新 : 10分登壇枠2つをパネルディスカッションへ変更しました。 # イベント概要 今までは iOS Test Night としてオフライン開催をしていましたが、今回はみなさんが気軽に参加していただけるよう iOS Test Online と題してオンラインで開催いたします! 本イベントはiOSにおけるテスト周りに関する知識を共有することを目的としたものです。 過去開催した関連イベントの資料は以下から参照可能となっております。 * iOS Test TeaTime * iOS Test Night # 開催形式 ## 発表 * Zoom...
❗ 2
👀 2
Avatar
treastrain / Tanaka.R 10/28/2022 11:07 AM
私も共有させていただきます🙇 Bitrise Pipelines に移行して、クレジットを節約しながら並列でビルド・テストを回す https://speakerdeck.com/treastrain/migrate-to-bitrise-pipelines-and-save-credits-while-run-builds-and-tests-in-parallel
Bitrise Pipelines に移行して、クレジットを節約しながら並列でビルド・テストを回す / Migrate to Bitrise Pipelines and save credits while run builds and tests in parallel iOS Test Online 2022/10/28 19:00〜 10分枠1 https://testonline.connpass.com/event/261910/
❤️ 2
Avatar
Avatar
Kuniwak
実践 9 つのメモリリークどう見つける?を発表してきました: https://speakerdeck.com/orgachem/how-to-detect-9-types-of-memory-leaks
XCTAssertNoLeakだ!ご紹介ありがとうございます🙌
t_waiwai 1
Avatar
XCTAssertGreaterThanで失敗すると「XCTAssertGreaterThan failed: (1) is not greater than (42)」のように表示されると思うのですが、成功した場合にも何かしらの表示をさせる方法はないですか? printすればいいんですが、出来ればXcodeのエディタ上に出てきて欲しくて。
Avatar
成功したらテストケース自体が緑に光るのでそれがその役割だと思います
11:01 AM
アサートの粒度でのそういうものはないと思います、なのでテストメソッドを細かく切るのが良いと思います (edited)
Avatar
なるほど……。デグレ防止で速度や精度のような量が一定の基準を超えているかをテストしたいんですが、実際どれだけだったのかも出来れば併せて知りたいという背景でした。
Avatar
omochimetaru 2/19/2023 1:22 PM
func XCTAssertGreaterThanOrPrint(_ actual: Float, _ expected: Float, file: StaticString = #file, line: UInt = #line) { if actual > expected { print("actual: \(actual)") return } XCTAssertGreaterThan(actual, expected, file: file, line: line) } こんな感じで print 付きのラッパーを作るとかですかね。 成功だけどエディタ上に表示する方法は知らないです、無い気がします。 (edited)
t_naruhodo 1
Avatar
なるほどー、ラッパー方式いいですね、ありがとうございます!!
Avatar
用途がいまいちよくわかってませんが、XCTExpectFailureはどうでしょうか?
Avatar
Avatar
Iceman
用途がいまいちよくわかってませんが、XCTExpectFailureはどうでしょうか?
omochimetaru 2/19/2023 1:59 PM
そんな世界反転法あるんや
2:00 PM
XCTExpectFailureとXCTFailをセットで使えば任意のメッセージをエディタに出せそうですね
Avatar
Avatar
Iceman
用途がいまいちよくわかってませんが、XCTExpectFailureはどうでしょうか?
ありがとうございます! 入念にコメント書かないと訳わからなくなりそうだけど、かなり求めていたものに近いです!
Avatar
どなたか業務でmaestroを試している方はいませんか。業務レベルのプロジェクトで運用していく際の課題や使用感などあれば知りたいです。 https://github.com/mobile-dev-inc/maestro (edited)
👍 1
👁️ 1
11:43 AM
こういうyamlでマルチプラットフォームなUIテストが書けるやつです https://twitter.com/mobile__dev/status/1580638270194491393
Avatar
↑とりあえずStoreKit configurationを渡す方法は提供されてなさそう
Avatar
Launch Argumentsと.storekitの対応してくれ〜とお願いしてみました https://github.com/mobile-dev-inc/maestro/issues/608 https://github.com/mobile-dev-inc/maestro/issues/945
👍 1
Avatar
Today we are excited to announce a completely new version of the iOS driver for Maestro, rebuilt from the ground up!
7:19 PM
unlike Appium, Maestro fully controls view matching and assertion logic. Where Appium delegates call to underlying XCUITest and Android’s Espresso frameworks, Maestro believes that it can do a better job than both by proactively pulling view hierarchy from the device and executing its own view-matching logic.
自前でViewのマッチングロジックを持つことで他のフレームワークを超えるのを目指しているらしい
🔥 1
ainame started a thread. 3/29/2023 4:33 PM
Avatar
Kishikawa Katsumi 5/2/2023 1:58 AM
テストをXcodeで実行したときは、それぞれのテストケースでどのAssertが失敗したかログが出るのだけど Test Suite 'GSetTests' started at 2023-05-02 09:56:52.910 Test Case '-[LWWElementDictionaryTests.GSetTests testAppend]' started. Test Case '-[LWWElementDictionaryTests.GSetTests testAppend]' passed (0.001 seconds). Test Case '-[LWWElementDictionaryTests.GSetTests testCompare]' started. Test Case '-[LWWElementDictionaryTests.GSetTests testCompare]' passed (0.001 seconds). Test Case '-[LWWElementDictionaryTests.GSetTests testContains]' started. Test Case '-[LWWElementDictionaryTests.GSetTests testContains]' passed (0.000 seconds). Test Case '-[LWWElementDictionaryTests.GSetTests testMerge]' started. Test Case '-[LWWElementDictionaryTests.GSetTests testMerge]' passed (0.000 seconds). Test Case '-[LWWElementDictionaryTests.GSetTests testReplace]' started. Test Case '-[LWWElementDictionaryTests.GSetTests testReplace]' passed (0.000 seconds). Test Case '-[LWWElementDictionaryTests.GSetTests testSubscript]' started. /Users/katsumi/Developer/LWWElementDictionary/LWWElementDictionaryTests/GSetTests.swift:70: error: -[LWWElementDictionaryTests.GSetTests testSubscript] : XCTAssertNil failed: "a" Test Case '-[LWWElementDictionaryTests.GSetTests testSubscript]' failed (0.015 seconds). Test Suite 'GSetTests' failed at 2023-05-02 09:56:52.929. Executed 6 tests, with 1 failure (0 unexpected) in 0.018 (0.019) seconds コマンドラインから実行したとき(xcodebuild test ~)は個々のテストケースのログが出なくなってる? Test suite 'GSetTests' started on 'My Mac - xctest (57795)' Test case 'GSetTests.testAppend()' passed on 'My Mac - xctest (57795)' (0.001 seconds) Test case 'GSetTests.testCompare()' passed on 'My Mac - xctest (57795)' (0.001 seconds) Test case 'GSetTests.testContains()' passed on 'My Mac - xctest (57795)' (0.000 seconds) Test case 'GSetTests.testMerge()' passed on 'My Mac - xctest (57795)' (0.001 seconds) Test case 'GSetTests.testReplace()' passed on 'My Mac - xctest (57795)' (0.008 seconds) Test case 'GSetTests.testSubscript()' failed on 'My Mac - xctest (57795)' (0.021 seconds)
💡 2
Avatar
Kishikawa Katsumi 5/16/2023 1:47 AM
Thank you for filing this feedback report. We reviewed your report and determined the behavior you experienced is currently functioning as intended. This is expected when running tests with parallel testing enabled. Xcodebuild output is not intended to be the primary way of accessing test results. Use the .xcresult bundle for that, with xcresulttool for scripting / automated systems. Alternatively, you could disable parallel testing for the bundle, or for the entire invocation by passing -parallel-testing-enabled NO to xcodebuild. If the issue is resolved, you can close this feedback by selecting “Close Feedback” via the Actions button found above. If we don’t hear from you in the next two weeks, we’ll assume the issue is resolved or not reproducible and will consider this issue closed. After this time, you can create a new Feedback report if the issue remains. Thank you.
これはAppleとしては意図的な変更らしい。-parallel-testing-enabled NO にしたら出るようになったけどどういうことなんだろう?コンソール出力が混ざるのを恐れているっていうことなのかな。
Avatar
Kishikawa Katsumi 5/17/2023 7:51 AM
書いてあるようにResult bundleの内容を出力するようなコードを追加したらいいっちゃいいんだけど、Result bundleに正しいログが記録できるならそれをコンソールに出してくれたらいいと思うんだよね。別にリアルタイム性はまったくいらないので。
Avatar
Kishikawa Katsumi 6/11/2023 12:43 AM
defaults write com.apple.dt.xcodebuild ParallelTestRunnerStdoutMirroringEnabled -bool YES このUser Defaultsを設定すると並列テストが有効でもログがちゃんと出るのをラボで教えてもらった。
❤️ 7
Avatar
Apple から新しいテストフレームワークが発表されました。 https://forums.swift.org/t/a-new-approach-to-testing-in-swift/67425 (edited)
Hi everyone, I’m excited to announce a new open source project exploring improvements to the testing experience for Swift. My colleagues @briancroom, @grynspan, @chefski, @Dennis and I have been working on this in recent months and have some early progress we're excited to share. Inspired by what’s possible with Swift macros, we’ve built a tes...
swift 10
👀 7
Avatar
Kishikawa Katsumi 9/21/2023 9:31 PM
使ってみよう。
Avatar
本質ではないですが CLI の swift test の出力結果の視認性が良くなったのは個人的にはかなり良かったです. XCTest の出力結果はよく目を凝らして読まないと成功したのか失敗したのかどのテストケースが失敗したのかがわからなくて辛かったので.
naruhodo 1
Avatar
Kishikawa Katsumi 9/22/2023 12:22 PM
そこいちばんの改善だと思うわ。XCTAssert*を使い分けなくてもよくなったし。
t_desune 3
Avatar
swift-testing は Swift ツールチェーンと一緒に配布されるようになるみたいですね. https://github.com/apple/swift-evolution/blob/main/visions/swift-testing.md
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - apple/swift-evolution
Avatar
おお。もう実用段階なんでしょうかね
Avatar
omochimetaru 6/8/2024 11:09 AM
そうなんだ。
11:10 AM
ビジョンドキュメント読みかけたけど、テストへの思いが丁寧に議論されてて、そんなに興味がないので離脱してもた
11:10 AM
テスト好きな人は読むと面白そう
Avatar
Avatar
Iceman
おお。もう実用段階なんでしょうかね
私が触っている限りの知識だと 5.10 時点では「試せるがまだ推奨はできない」みたいな感じですね.Vim とか VS Code で Swift package の開発をしているだけの人にはほとんど問題ないですが,Xcode で開発している人は Xcode の GUI 側がまだ何も対応していないから不便な思いをすると思います.WWDC に期待.
Avatar
omochimetaru 6/8/2024 11:50 AM
Xcode の GUI 側がまだ何も対応していない
あ〜 そうなんだ。
Avatar
なるほど。Xcode中心なのでそこないのは痛いですね
Avatar
SWET でも色々みてみましたけど、まだ使う段階ではないという結論になっています
😔 2
Avatar
Swift Testing is a new framework with expressive and intuitive APIs that make testing your Swift code a breeze.
🎉 7
Avatar
おお、良さげ!
Avatar
Kishikawa Katsumi 6/11/2024 9:14 AM
XcodeのUIはめっちゃいいと思う。これCIでテキストで見たときにどうなるんやろう。
Avatar
Avatar
Kishikawa Katsumi
XcodeのUIはめっちゃいいと思う。これCIでテキストで見たときにどうなるんやろう。
@Testarguments でテストケースを増やしてますが,0.10.0 時点ではこんな感じですね.(xcodebuild じゃないのでそこで違いはあるかもしれないですが) https://github.com/kkebo/zyphy/actions/runs/9456496307/job/26048489628#step:7:387 (edited)
Avatar
Kishikawa Katsumi 6/11/2024 10:41 AM
失敗したときのが見たいです。Xcodeだとオブジェクトを見やすく表示してくれてとてもいいと思いますが、CIだと難しいんじゃないかと。
t_naruhodo 1
Avatar
途中がこんな風になる感じですね. ◇ Test run started. ↳ Testing Library Version: 69d59cfc76e5daf498ca61f5af409f594768eef9 ◇ Test "html5lib-tests" started. ◇ Test namedCharRef() started. ◇ Test basicHTML() started. (中略) ◇ Passing 1 argument testCase → \u000B (scriptData) to "html5lib-tests" ◇ Passing 1 argument testCase → \u000B (cdataSection) to "html5lib-tests" ✘ Test "html5lib-tests" recorded an issue with 1 argument testCase → \u000B (plaintext) at HTML5LibTests.swift:45:5: Expectation failed: (tokenizer.sink.errors.count → 0) == (testCase.errors.count → 1) ✘ Test "html5lib-tests" recorded an issue with 1 argument testCase → \u000B (rcdata) at HTML5LibTests.swift:45:5: Expectation failed: (tokenizer.sink.errors.count → 0) == (testCase.errors.count → 1) ✘ Test "html5lib-tests" recorded an issue with 1 argument testCase → \u000B (scriptData) at HTML5LibTests.swift:45:5: Expectation failed: (tokenizer.sink.errors.count → 0) == (testCase.errors.count → 1) ◇ Passing 1 argument testCase → \u000C to "html5lib-tests" ◇ Passing 1 argument testCase → \u000C (plaintext) to "html5lib-tests" ✘ Test "html5lib-tests" recorded an issue with 1 argument testCase → \u000B (rawtext) at HTML5LibTests.swift:45:5: Expectation failed: (tokenizer.sink.errors.count → 0) == (testCase.errors.count → 1) ◇ Passing 1 argument testCase → \u000C (scriptData) to "html5lib-tests" ◇ Passing 1 argument testCase → \u000C (rawtext) to "html5lib-tests" ✘ Test "html5lib-tests" recorded an issue with 1 argument testCase → \u000B (cdataSection) at HTML5LibTests.swift:45:5: Expectation failed: (tokenizer.sink.errors.count → 1) == (testCase.errors.count → 2) ◇ Passing 1 argument testCase → \u000C (rcdata) to "html5lib-tests" ◇ Passing 1 argument testCase → \u000C (cdataSection) to "html5lib-tests" (中略) ✘ Test "html5lib-tests" failed after 0.174 seconds with 190 issues. ✘ Test run with 3 tests failed after 0.175 seconds with 190 issues.
11:01 AM
ここに貼り付けると word wrap されて違う見え方になっちゃいますね...
Avatar
キャプチャが良さそう
Avatar
Avatar
kebo
@Testarguments でテストケースを増やしてますが,0.10.0 時点ではこんな感じですね.(xcodebuild じゃないのでそこで違いはあるかもしれないですが) https://github.com/kkebo/zyphy/actions/runs/9456496307/job/26048489628#step:7:387 (edited)
これをところどころこけるようにした時がこんな感じですね. https://github.com/kkebo/zyphy/actions/runs/9464385767/job/26071613710?pr=90#step:7:488
11:11 AM
失敗するようにしたところが count の比較のところだとあまり意味がないか...
Avatar
Kishikawa Katsumi 6/11/2024 11:13 AM
やっぱりオブジェクトの構造を比べるようなリッチなDiffはXcodeのUIで見る感じかな。
Avatar
enum の Array の比較だとこういう感じです ✘ Test "html5lib-tests" recorded an issue with 1 argument testCase → Truncated doctype start at HTML5LibTests.swift:44:5: Expectation failed: (tokenizer.sink.tokens → [Tokenizer.Token.comment(["!", "D", "O", "C"]), Tokenizer.Token.eof]) == (testCase.tokens → [Tokenizer.Token.comment(["D", "O", "C"]), Tokenizer.Token.eof]) ± inserted [Tokenizer.Token.comment(["!", "D", "O", "C"])], removed [Tokenizer.Token.comment(["D", "O", "C"])]
Avatar
Kishikawa Katsumi 6/11/2024 11:23 AM
こういうのがどうなるか試せます?
Avatar
Avatar
Kishikawa Katsumi
こういうのがどうなるか試せます?
こうなりますね. ✘ Test namedCharRef() recorded an issue at HTMLEntitiesTests.swift:16:5: Expectation failed: (Metadata(duration: .seconds(0), resolution: .init(width: 1920, height: 1080)) → Metadata(duration: 0.0 seconds, resolution: Foundation.CGSize(width: 1920.0, height: 1080.0))) == (Metadata(duration: .seconds(90), resolution: .init(width: 3840, height: 2160)) → Metadata(duration: 90.0 seconds, resolution: Foundation.CGSize(width: 3840.0, height: 2160.0)))
11:29 AM
よくみたら解決案を提示してくれてますね. 勘違いでした (edited)
Avatar
Kishikawa Katsumi 6/11/2024 11:30 AM
お、省略とかされずに値がちゃんと出てるからいいですね。
Avatar
CustomDebugStringConvertible を真面目に実装しているかデフォルト実装ならちゃんと出るみたいですね. 逆に CustomDebugStringConvertibledebugDescription"hoge" とか返すようにしていると残念なことになっちゃいます.(Data の比較とか) ✘ Test namedCharRef() recorded an issue at HTMLEntitiesTests.swift:23:5: Expectation failed: (Metadata(duration: .seconds(0), resolution: .init(width: 1920, height: 1080)) → hoge) == (Metadata(duration: .seconds(90), resolution: .init(width: 3840, height: 2160)) → hoge) (edited)
11:40 AM
と思ったら Data は inserted と removed で Array の時と同じくイテレートできる要素単位で教えてくれるっぽいです. ✘ Test namedCharRef() recorded an issue at HTMLEntitiesTests.swift:22:5: Expectation failed: ("hoge".data(using: .utf8)! → 4 bytes) == ("fuga".data(using: .utf8)! → 4 bytes) ± inserted [104, 111, 101], removed [102, 117, 97]
Avatar
Kishikawa Katsumi 6/11/2024 11:44 AM
Diff出してくれるのか。よくできてる。
Avatar
MirrorDiffKit いらなくなる機運です?
1:23 PM
最近メンテしたばっか 😭
Avatar
Kishikawa Katsumi 6/11/2024 2:21 PM
特にターミナルにTestのDiffをわかりやすく表示するのはノウハウがいるしテストの内容にもよるのでswift-testingで100%カバーできることはないと思いますね。
2:22 PM
結果をDiffで表示したいようなそれなりに複雑なケースは特に。
Avatar
Avatar
Kishikawa Katsumi
やっぱりオブジェクトの構造を比べるようなリッチなDiffはXcodeのUIで見る感じかな。
(直前の話とは変わっちゃいますが) そういえば UI のインテグレーションは Xcode だけじゃなくて VS Code もサポートされているみたいですね.まだ試していないですが.
Avatar
Kishikawa Katsumi 6/11/2024 2:59 PM
なんかUIに表示するためのメタデータが出力されてたりしないかと気になっています。
3:00 PM
まあテストケースをまとめたり実行ボタンを付けるのはXcodeがやってるのと同じことをしてるのかもしれない。 結果はResult Bundleを見れば全部はいってるのかな?
Avatar
--experimental-event-stream-output フラグ付きでテストバイナリをビルドするとテストバイナリがテスト中のイベントを named pipe に吐き出してくれるようになって,VS Code extension 側でその named pipe を監視するみたいな仕組みみたいですね.(他にも細々した工夫があるんでしょうけれど) https://github.com/swiftlang/vscode-swift/pull/775
Avatar
今だと Linux では swift-testing は swift-testing パッケージを依存関係に追加しないと使えないですが,今後はツールチェーンに同梱して macOS と同様に外部パッケージの追加なしで使えるようにする予定ではあるみたいですね. https://github.com/swiftlang/swift/pull/74582
As mentioned in the (now approved) A New Direction for Testing in Swift vision document, we're planning to include the swift-testing project in Swift toolchains soon. In preparation for that, t...
🎉 3
Avatar
Avatar
kebo
今だと Linux では swift-testing は swift-testing パッケージを依存関係に追加しないと使えないですが,今後はツールチェーンに同梱して macOS と同様に外部パッケージの追加なしで使えるようにする予定ではあるみたいですね. https://github.com/swiftlang/swift/pull/74582
6.0 の snapshot toolchain だと今日出た swift-6.0-DEVELOPMENT-SNAPSHOT-2024-09-11-a からようやく swift-testing パッケージを依存関係に追加しなくても Testing モジュールを import して使えるようになってました.
👏 2
Avatar
データセットをまとめて各テストで加工して渡すっていうのをやりたかったんですけどコンパイラに怒られました 🫠 @Suite struct SomeTest { private static let dataSets: [(a: String, b: String, _ c: String)] = [ ("a", "b", "c"), ("d", "e", "f"), ] @Test(arguments: dataSets) // ← OK func doSomethingABC(_ a: String, _ b: String, c: String) { } @Test(arguments: dataSets.map { ($0.a, $0.b) }) // ← NG func doSomethingAB(_ a: String, _ b: String) { } @Test(arguments: dataSets.map { ($0.a, $0.c) }) // ← NG func doSomethingAC(_ a: String, _ c: String) { } } (edited)
Avatar
private static let dataSetsAB と dataSetsAC を作っておくしかないですかね
Avatar
マクロ引数部分には優しい式を入れる必要がありますよね
Avatar
後でIssueは投げるとして、データセット分けたくは無いので3変数でお茶を濁すことにしました 🫠 @Suite struct SomeTest { private static let dataSets: [(a: String, b: String, c: String)] = [ ("a", "b", "c"), ("d", "e", "f"), ] @Test(arguments: dataSets) func doSomethingABC(_ a: String, _ b: String, _ c: String) { } @Test(arguments: dataSets) func doSomethingAB(_ a: String, _ b: String, _: String) { } @Test(arguments: dataSets) func doSomethingAC(_ a: String, _: String, _ c: String) { } } (edited)
Avatar
マクロパラメータ部分に書ける式ってどういう仕様なんだろう
11:31 AM
型チェックはされるけど式を扱えるかどうかはマクロ実装次第?
Avatar
そうですね。マクロ引数の型があってるかはSwiftによって処理されるけど、中の式の処理は全部マクロ実装側で、既にオーバーロードとか処理してて十分複雑なので複雑な式は対応できないんだと予想してます (edited)
Avatar
うーむ・・・ なんか形式的じゃなくて気持ち悪いんだよなあ
Avatar
Kishikawa Katsumi 10/10/2024 5:08 PM
マクロから型にアクセスできるようになると解決すると思うけど(式を分割できるようになるので)いつになるかな。 (edited)
Exported 530 message(s)
Timezone: UTC+0