Pythonでのテストすべおの䞻芁なアプロヌチ、長所ず短所。Yandexレポヌト

あなたの前にマリア・れレノノァの報告がありたす れルマ--Foodilの開発者。マヌシャは1時間、テストプログラムずは䜕か、テストずは䜕か、なぜそれらを曞くのかを話したした。簡単な䟋を䜿甚しお、Pythonコヌドunittest、pytest、mockをテストするためのラむブラリ、それらがどのように機胜するか、およびそれらの違いに぀いお孊ぶこずができたす。





-こんばんは、私の名前はマヌシャです。私ぱディラのデヌタ分析郚門で働いおいたす。今日はあなたず䞀緒にテストに぀いおの講矩をしたす。







最初に、䞀般的にどのような皮類のテストがあるかに぀いお話し合い、なぜテストを䜜成する必芁があるのか​​を玍埗させようずしたす。次に、テストを盎接操䜜するためのPythonの機胜ず、テストの䜜成モゞュヌルおよび補助モゞュヌルに぀いお説明したす。最埌に、CIに぀いお少しお話したす。これは倧䌁業での生掻の必然的な郚分です。







䟋から始めたいず思いたす。テストを曞く䟡倀がある理由を非垞に恐ろしい䟋で説明しようず思いたす。



これがTHERAC25プログラムのむンタヌフェヌスです。これは癌患者の攟射線治療甚の装眮の名前であり、すべおが非垞にうたくいきたせんでした。たず第䞀に、それは悪いむンタヌフェヌスを持っおいたした。圌を芋るず、圌があたり良くないこずはすでに理解できたす。医垫がこれらすべおの数字を運転するのは䞍䟿でした。その結果、圌らは前の患者の蚘録からデヌタをコピヌし、線集する必芁があるものだけを線集しようずしたした。



圌らが半分を修正するのを忘れお、間違っおいたのは明らかです。その結果、患者は誀っお扱われたした。 UIもテストする䟡倀があり、テストが倚すぎるこずはありたせん。



しかし、悪いむンタヌフェヌスに加えお、バック゚ンドにはさらに倚くの問題がありたした。私が最もひどいず思われる2぀を特定したした。



  • . , . , . , .
  • C . THERAC , — , . . , , , - , - — .


テストを曞く䟡倀があるでしょう。それは5人の蚘録された死に終わったので、そしお䜕人の人々があたりにも倚くの薬を䞎えられたこずで苊しんでいるのかは䞍明です。







状況によっおは、テストを䜜成するこずで倚くのお金を節玄できるずいう別の䟋がありたす。これは火星気候オヌビタヌです。火星の倧気䞭の倧気を枬定しお、そこで気候に䜕が起こっおいるかを確認するための装眮です。



しかし、地䞊にあったモゞュヌルは、メトリックシステムのSIシステムでコマンドを実行したした。そしお火星の軌道にあるモゞュヌルは、それが英囜の察策システムであるず考え、それを誀っお解釈したした。



その結果、モゞュヌルは間違った角床で倧気に入り、厩壊したした。テストで状況をシミュレヌトしおこれを回避するこずは可胜であるように思われたすが、1億2500䞇ドルがゎミ箱に入ったばかりです。しかし、それはうたくいきたせんでした。



ここで、テストを䜜成する必芁がある理由に぀いお説明したす。各項目に぀いお個別に話したしょう



  • テストは、コヌドが機胜するこずを確認し、少し萜ち着かせたす。テストを䜜成した堎合は、コヌドが機胜するこずを確認できたす。もちろん、適切に䜜成した堎合はそうです。よく眠れ。それは非垞に重芁です。
  • . . , , , . , . , .



    , - , — , - . , . , , . , , , git blame, , , , .
  • . , . , . , , . - - , - - . , , , . - .
  • , . ? , , , , : , . 500 -, . . .
  • : — . , , . , , .



    , , , . , , .
  • . — , . , , . , .



    : - . , , . , , , - , .


ここで、テストの皮類の分類に぀いお少しお話したいず思いたす。それらはたくさんありたす。ほんの少しだけ蚀及したす。



テストプロセスは、ブラックボックステスト、ホワむトテスト、グレヌテストに分けられたす。







ブラックボックステストは、テスタヌが内郚の内容に぀いお䜕も知らない堎合のプロセスです。圌は、普通のナヌザヌのように、実装の詳现を知らなくおも䜕かをしたす。



ホワむトボックステストずは、テスタヌが゜ヌスコヌドを含む必芁な情報にアクセスできるこずを意味したす。自分のコヌドでテストを曞くずき、私たちはそのような状況にありたす。



グレヌボックステストはその䞭間です。これは、実装の詳现をいく぀か知っおいるが、すべおを知っおいるわけではない堎合です。



たた、テストプロセスは、手動、半自動、および自動に分けるこずができたす。手動テストは人が行いたす。圌がブラりザのボタンをクリックし、どこかをクリックし、䜕が壊れおいるか、䜕が壊れおいないかを確認するずしたす。半自動テストずは、テスタヌがテストスクリプトを実行するこずです。テストをロヌカルで実行する堎合、このような状況にあるず蚀えたす。自動テストには人間の参加は含たれたせん。テストは手動ではなく自動的に実行する必芁がありたす。



たた、テストは詳现レベルで分割できたす。ここでは通垞、ナニットテストず統合テストに分けられたす。䞍䞀臎がある可胜性がありたす。自動テストをナニットテストず呌ぶ人がいたす。しかし、より叀兞的な区分はこのようなものです。



ナニットテストはシステムの個々のコンポヌネントの動䜜をチェックし、統合テストはいく぀かのモゞュヌルのバンドルをチェックしたす。システム党䜓の動䜜をチェックするシステムテストもありたす。しかし、これは統合テストの倧きな倉皮のようです。



私たちのコヌドのテストは、ナニットテストず統合テストです。統合テストだけを曞くべきだず信じおいる人がいたす。私はその䞀人ではありたせん。すべおを適床に行う必芁があるず思いたす。1぀のコンポヌネントをテストする堎合のナニットテストず、倧きなものをテストする堎合の統合テストの䞡方が圹立ちたす。



なぜそう思うのですかナニットテストは通垞​​より高速だからです。䜕かを埮調敎する必芁がある堎合、「テストの実行」ボタンをクリックしおから、デヌタベヌスが開始され、移行が行われるたで3分間埅぀ず、非垞にむラむラしたす。䜕か別のこずが起こりたす。このような堎合、ナニットテストが圹立ちたす。それらは、䞀床に1぀ず぀実行しお、すばやく䟿利に実行できたす。しかし、ナニットテストを修正したら、統合テストを修正したしょう。



統合テストも非垞に必芁なものです。倧きなプラスは、それらがシステムに関するものであるずいうこずです。もう1぀の倧きな利点は、コヌドのリファクタリングに察する耐性が高いこずです。小さな関数を曞き盎す可胜性が高い堎合は、パむプラむン党䜓を同じ頻床で倉曎する可胜性はほずんどありたせん。







さらに倚くの異なる分類がありたす。私がここに曞いたこずをすぐに説明したすが、詳现には觊れたせん。これらはどこかで聞くこずができる蚀葉です。



煙テストは重芁な機胜のテストであり、最初で最も単玔なテストです。それらが壊れた堎合、テストする必芁はありたせんが、修正する必芁がありたす。アプリケヌションが起動し、クラッシュしなかったずしたしょう。すばらしい、スモヌクテストに合栌したした。



回垰テストがありたす-叀い機胜のテスト。新しいリリヌスをロヌルし、叀いリリヌスで䜕も壊れおいないこずを確認する必芁があるずしたす。これは回垰テストのタスクです。



互換性テスト、むンストヌルテストがありたす。圌らは、さたざたなOSずさたざたなOSバヌゞョン、さたざたなブラりザずさたざたなブラりザバヌゞョンで、すべおが正しく機胜するこずを確認したす。



受け入れテストは受け入れテストです。私はすでにそれらに぀いお話したした、圌らはあなたの倉曎が本番環境にロヌルむンできるかどうかに぀いお話したす。



アルファテストずベヌタテストもありたす。これらの抂念はどちらも、補品に関連しおいたす。通垞、リリヌスの準備ができおいるバヌゞョンが倚かれ少なかれあるが、すべおがそこで修正されおいるわけではない堎合は、条件付きで倖郚の人々、たたは倖郚の人々、ボランティアにそれを枡しお、バグを芋぀けお報告し、非垞に優れたバヌゞョンをリリヌスできるようにするこずができたす。アルファ版の完成床が䜎いほど、ベヌタ版の完成床は高くなりたす。ベヌタテストでは、ほずんどすべおが今では問題ないはずです。



次に、パフォヌマンステストずストレステスト、負荷テストがありたす。たずえば、アプリケヌションが負荷をどのように凊理しおいるかをチェックしたす。いく぀かのコヌドがありたす。ナヌザヌ数、リク゚スト数、RPS、1秒あたりのリク゚スト数を蚈算したした。私たちはこの状況をシミュレヌトし、立ち䞊げ、芋たした-それは成り立ちたすが、成り立ちたせん。それが成り立たない堎合は、次に䜕をすべきかを考えおください。おそらく、コヌドを最適化するか、ハヌドりェアの量を増やすために、さたざたな゜リュヌションがありたす。



ストレステストはほが同じですが、負荷が予想よりも高いだけです。パフォヌマンステストで期埅するレベルの負荷が埗られた堎合、ストレステストでは、負荷が壊れるたで負荷を増やすこずができたす。



リンタヌはここで別々に立っおいたす。リンタヌに぀いおは少し埌で説明したす。これらはコヌドフォヌマットテストであり、スタむルガむドです。 Pythonでは、誰もが埓うべき簡単なスタむルガむドであるPEP8がありたす。そしお、あなたが䜕かを曞くずき、あなたは通垞、コヌドに埓うのが難しいこずに気づきたす。空の行を入力するのを忘れた、䜙分な行を䜜成した、たたは長すぎる行を残したずしたす。コヌドが同じスタむルで曞かれおいるこずに慣れおいるので、邪魔になりたす。リンタヌを䜿甚するず、そのようなものを自動的にキャッチできたす。



理論、すべお、それから私はPythonに䜕があるかに぀いお話したす。







これがいく぀かのラむブラリのリストです。それらすべおに぀いおは詳しく説明したせんが、ほずんどに぀いおは説明したす。もちろん、unittestずpytestに぀いおも説明したす。これらは、テストの䜜成に盎接䜿甚されるラむブラリです。 Mockは、モックオブゞェクトを䜜成するためのヘルパヌラむブラリです。圌女に぀いおも話したす。 doctestはドキュメントをテストするためのモゞュヌルであり、flake8はリンタヌです。これらに぀いおも説明したす。ピラマずトックスに぀いおは話したせん。あなたが興味を持っおいるなら、あなたはあなた自身のために芋るこずができたす。ピラマはリンタヌでもあり、メタルむンタヌでもあり、いく぀かのパッケヌゞを組み合わせおおり、非垞に䟿利で優れおいたす。たた、さたざたな環境でコヌドをテストする必芁がある堎合、たずえば、さたざたなバヌゞョンのPythonやさたざたなバヌゞョンのラむブラリを䜿甚しお、toxラむブラリが必芁になりたす。 Toxはこの意味で倧いに圹立ちたす。



しかし、さたざたなラむブラリに぀いお話す前に、私は陳腐さから始めたす。コヌドでassertを自由に䜿甚しおください。それは残念ではありたせん。倚くの堎合、䜕が起こっおいるのかを理解するのに圹立ちたす。







通垞の統蚈を蚈算する関数があるずするず、2぀のアサヌトが曞き蟌たれたす。アサヌトは、コヌドに含めるべきではない完党に極端なナンセンスである堎合に、関数で蚘述する必芁がありたす。これらは非垞に極端なケヌスであり、ほずんどの堎合、本番環境でそれらに遭遇するこずさえありたせん。぀たり、コヌドを台無しにするず、テストで倱敗する可胜性が高くなりたす。



アサヌトは、プロトタむピングを行っおいるずきに圹立ちたす。補品コヌドはただありたせん。呌び出された関数のどこにいおも、どこにでもアサヌトを固定できたす。これは深刻なプロゞェクトには適しおいたせんが、プロトタむピングの段階ではかなり良いです。



なんらかの理由でassertを無効にしたい堎合を考えおみたしょう。たずえば、本番環境では決しお起動しないようにしたす。 Pythonには、このための特別なオプションがありたす。







doctestずは䜕かをお話ししたす。これはモゞュヌルであり、ドキュメントをテストするためのPython暙準ラむブラリです。なんでいいのコヌドで曞かれたドキュメントは頻繁に壊れがちです。ここには非垞に小さなおもちゃの機胜があり、すべおを芋るこずができたす。しかし、倧きなコヌドず倚くのパラメヌタヌがあり、最埌に䜕かを远加した堎合、非垞に高い確率でdocstringを修正するのを忘れおしたいたす。 Doctestはこれらのこずを回避したす。䜕かを修正し、ここで曎新せず、doctestを実行するず、クラッシュしたす。ですから、あなたは自分が䜕を蚂正しなかったかを正確に芚えおいたす。



それはどのように芋えたすか Doctestは、docstringでこれらのクリスマスツリヌを探し、それらを実行しお、取埗したものを比范したす。







doctestの実行䟋を次に瀺したす。私たちはそれを立ち䞊げたした、私たちは2぀のテストがあり、そのうちの1぀が完党にケヌスに萜ちたこずがわかりたす。すばらしい、明確な゚ラヌ情報がいく぀か芋られたした。





スラむドからのリンク



doctestには、圹立぀可胜性のあるいく぀かの圹立぀ディレクティブがありたす。それらすべおに぀いお話すわけではありたせんが、私にずっお最も䞀般的であるず思われるものをスラむドに茉せたした。 SKIPディレクティブを䜿甚するず、マヌクされた䟋でテストを実行しないこずができたす。 IGNORE_EXCEPTION_DETAILディレクティブは、EXCEPTIONテストを無芖したす。 ELLIPSISを䜿甚するず、出力のどこにでも゚リプシスを曞き蟌むこずができたす。 FAIL_FASTは、最初に倱敗したテストの埌で停止したす。他のすべおはドキュメントで読むこずができたす、たくさんありたす。䟋を挙げおお芋せしたほうがいいです。







この䟋には、ELLIPSISディレクティブずIGNORE_EXCEPTION_DETAILディレクティブがありたす。 ELLIPSISディレクティブにK番目の順序統蚈が衚瀺されたす。9で始たり9で終わる䜕かが来るず予想されたす。真ん䞭に䜕かがある可胜性がありたす。そのようなテストは倱敗したせん。



以䞋はIGNORE_EXCEPTION_DETAILディレクティブであり、AssertionErrorで発生したもののみをチェックしたす。ほら、そこに䜕ずか䜕ずか䜕ずか曞いた。テストは合栌し、最初の匕数ずしお予想される反埩可胜ず䜕ずか䜕ずか䜕ずかを比范したせん。 AssertionErrorをAssertionErrorず比范するだけです。これらはあなたが䜿うこずができる䟿利なものです。







次に、蚈画は次のずおりです。unittestに぀いお説明し、次にpytestに぀いお説明したす。それが暙準ラむブラリの䞀郚であるこずを陀いお、私はおそらくunittestの長所を知らないずすぐに蚀いたす。珟圚、unittestを䜿甚せざるを埗ない状況は芋圓たりたせん。しかし、それを䜿甚するプロゞェクトがありたす。いずれにせよ、構文がどのように芋えるか、そしおそれが䜕であるかを知るこずは有甚です。



もう1぀のポむントunittestで蚘述されたテストは、箱から出しおすぐにpytestを実行する方法を知っおいたす。圌は気にしない。  



Unittestはこんな感じ。テストずいう蚀葉で始たるクラスがありたす。内郚では、単語テストで始たる関数。テストクラスはunittest.TestCaseから継承したす。ここでの1぀のテストは正しく蚘述されおおり、別のテストは正しくないこずをすぐに蚀わなければなりたせん。



通垞のアサヌトが曞き蟌たれる䞀番䞊のテストは倱敗したすが、奇劙に芋えたす。芋おみたしょう。







コマンドを開始したす。 unittest mainはコヌド自䜓に蚘述でき、Pythonから呌び出すこずができたす。







このテストを実行したずころ、AssertionErrorが曞き蟌たれたこずがわかりたしたが、self.assertEqualを䜿甚した次のテストずは異なり、どこに萜ちたかは曞き蟌たれたせんでした。ここに明確に曞かれおいたす3は2ず等しくありたせん。







もちろん、修理する必芁がありたす。しかし、この魔法の出力は画面に衚瀺されたせんでした。



もう䞀床芋おみたしょう。最初のケヌスでは、assertを蚘述し、2番目のケヌスではself.assertEqualを蚘述したした。残念ながら、これがunittestの唯䞀の方法です。特別な関数がありたす-self.assertEqual、self.assertnotEqual、および適切な゚ラヌメッセヌゞを衚瀺したい堎合に䜿甚する必芁がある100,500以䞊の関数。



なぜそれが起こるのですか assertはboolず、堎合によっおは文字列を受け取るステヌトメントですが、この堎合はboolです。そしお、圌は自分が正しいか間違っおいるかを芋お、巊偎ず右偎をずる堎所がありたせん。したがっお、unittestには、゚ラヌメッセヌゞを正しく衚瀺する特別な機胜がありたす。



これは私の意芋ではあたり䟿利ではありたせん。より正確には、これらはこのラむブラリにのみ存圚するいく぀かの特別なメ゜ッドであるため、たったく䟿利ではありたせん。それらは、私たちが通垞の蚀語で慣れおいるものずは異なりたす。







これを芚えおおく必芁はありたせん。pytestに぀いおは埌で説明したす。ほずんどの堎合、これに曞き蟌んでいただければ幞いです。 Unittestには、䜕かをテストしお適切な゚ラヌメッセヌゞを取埗したい堎合に䜿甚する機胜の動物園がありたす。



次に、unittestでフィクスチャを䜜成する方法に぀いお説明したす。しかしそれをするために、私は最初にあなたに備品が䜕であるかを蚀う必芁がありたす。これらは、テストの実行前たたは実行埌に呌び出される関数です。テストで特別な蚭定を実行する必芁がある堎合に必芁です。テスト埌に䞀時ファむルを䜜成し、䞀時ファむルを削陀したす。デヌタベヌスを䜜成し、デヌタベヌスを削陀したす。デヌタベヌスを䜜成し、それに䜕かを曞き蟌みたす。䞀般的に、䜕でも。 unittestでどのように芋えるか芋おみたしょう。







Unittestには、フィクスチャを䜜成するための特別なメ゜ッドsetUpおよびtearDownがありたす。なぜただPEP8に埓っお曞かれおいないのか、私には倧きな謎です。 ...



SetUpはテストの前に行われるこずであり、tearDownはテストの埌に行われるこずです。これは非垞に䞍䟿なデザむンのようです。どうしおなぜなら、第䞀に、私の手はこれらの名前を曞くために立ち䞊がらないからです。私はすでにPEP8がただある䞖界に䜏んでいたす。次に、テスト自䜓の匕数に䜕も含たれおいない䞀時ファむルがありたす。圌はどこから来たのですかなぜそれが存圚するのか、そしおそれが䜕であるのかはあたり明確ではありたせん。



画面にしがみ぀く小さなクラスがあるず、かっこいいです。䞀芋しおキャプチャできたす。そしお、あなたがこの巚倧なシヌトを持っおいるずき、あなたはそれが䜕であったか、そしおなぜ圌がそのようであるのか、なぜ圌がそのように振る舞うのかを探すために苊しめられたす。



unittestのフィクスチャには、それほど䟿利ではない機胜がもう1぀ありたす。䞀時ファむルを必芁ずする1぀のテストクラスず、デヌタベヌスを必芁ずする別のテストクラスがあるずしたす。優れた。 1぀のクラスを䜜成し、setUp、tearDownを実行し、䞀時ファむルを䜜成/削陀したした。別のクラスを䜜成し、その䞭にsetUp、tearDownを䜜成し、その䞭にデヌタベヌスを䜜成/削陀したした。



質問。䞡方を必芁ずするテストの3番目のグルヌプがありたす。これをどうするか 2぀の遞択肢がありたす。たたは、コヌドをコピヌしお貌り付けたすが、あたり䟿利ではありたせん。たたは、新しいクラスを䜜成し、前の2぀から継承しお、superを呌び出したす。䞀般的に、これも機胜したすが、テストでは倧げさなやり過ぎのように芋えたす。







したがっお、理論的なレベルでは、unittestに぀いおの知識をこのたたにしおおく必芁がありたす。次に、テストを䜜成するためのより䟿利な方法、より䟿利なラむブラリに぀いお説明したす。これはpytestです。



たず、pytestが䟿利な理由をお話ししたす。





スラむドからのリンク



最初のポむントpytestでは、アサヌトは通垞は機胜し、慣れおいるものであり、通垞の゚ラヌ情報を提䟛したす。第二に、pytestの優れたドキュメントがありたす。ここでは、倚数の䟋が分解され、必芁なものはすべお、理解できないものすべおを衚瀺できたす。



第䞉に、テストはtest_で始たる関数にすぎたせん。぀たり、远加のクラスは必芁ありたせん。通垞の関数を蚘述し、それをtest_ず呌ぶだけで、pytestを介しお実行されたす。これは、テストを䜜成するのが簡単であるほど、スコアを付けるよりもテストを䜜成する可胜性が高くなるため、䟿利です。



Pytestには䟿利な機胜がたくさんありたす。パラメヌタ化されたテストを䜜成できたす。さたざたなレベルのフィクスチャを䜜成するず䟿利です。たた、xfail、raise、skipなどの䟿利な機胜もいく぀かありたす。 pytestには倚くのプラグむンがあり、さらに独自のプラグむンを䜜成するこずもできたす。







䟋を芋おみたしょう。これは、pytestで蚘述されたテストがどのように芋えるかです。意味はunittestず同じですが、芋た目がはるかに簡朔です。最初のテストは通垞​​2行です。







コマンドpython-mpytestを実行したす。優れた。 2぀のテストに合栌したした。すべお問題ありたせん。䜕に、い぀合栌したかを確認できたす。







それでは、1぀のテストを䞭断しお、゚ラヌに関する情報が埗られるようにしたす。アサヌト3 == 2および゚ラヌを出力したす。぀たり、通垞のassertを蚘述したにもかかわらず、゚ラヌに関する情報を正しく衚瀺したしたが、その前にunittestで、assertは文字列たたはboolのboolを受け入れるず述べたため、゚ラヌに関する情報を衚瀺するのは問題がありたす。



なぜこれがすべお機胜するのか䞍思議に思うかもしれたせん。 pytestで、圌らはむンタヌフェヌスの醜い郚分を詊しお敎理したからです。 Pytestは最初にコヌドを解析し、それは䞀皮のツリヌ構造、抜象的な構文ツリヌずしお衚瀺されたす。この構造では、頂点に挔算子があり、葉にオペランドがありたす。アサヌトは挔算子です。それはツリヌの最䞊郚にあり、珟時点では、すべおをむンタヌプリタヌに枡す前に、このアサヌトを、むントロスペクションを実行し、巊偎ず右偎にあるものを理解する内郚関数に眮き換えるこずができたす。実際、これはすでにむンタヌプリタヌに䟛絊されおおり、assertが眮き換えられおいたす。



詳现には立ち入りたせん、リンクがありたす、その䞊であなたは圌らがそれをどのようにしたかを読むこずができたす。しかし、私はそれがすべお内郚で機胜するこずを愛しおいたす。ナヌザヌには衚瀺されたせん。圌は、圌が慣れおいるように、ラむブラリ自䜓が残りを行うず䞻匵したす。あなたもそれに぀いお考える必芁はありたせん。



さらに、暙準タむプのpytestでは、ずにかく適切な゚ラヌ情報が埗られたす。 pytestはこの゚ラヌ情報を衚瀺する方法を知っおいるからです。ただし、テストでカスタムデヌタタむプを比范するこずはできたす。たずえば、ツリヌや耇雑なものなどです。pytestは、それらの゚ラヌ情報を衚瀺する方法を知らない堎合がありたす。このような堎合は、特別なフックを远加できたすここにドキュメントのセクションがありたす。このフックに、゚ラヌ情報がどのように衚瀺されるかを蚘述したす。すべおが非垞に柔軟で䟿利です。







pytestでフィクスチャがどのように芋えるか芋おみたしょう。 unittestでsetUpずtearDownを蚘述する必芁がある堎合は、ここで通垞の関数を奜きなように呌び出したす。 pytest.fixtureデコレヌタを䞀番䞊に曞きたした-玠晎らしい、それはフィクスチャです。



そしお、これは最も単玔な䟋ではありたせん。フィクスチャは単にリタヌンを実行し、䜕かを返すこずができたす。これはsetUpに類䌌しおいたす。この堎合、䞀皮のティアダりンが発生したす。぀たり、ここで、テストの終了埌にcloseが呌び出され、䞀時ファむルが削陀されたす。



䟿利そうです。奜きな名前を付けるこずができる任意の関数がありたす。明瀺的にテストに合栌したす。枡されたfilled_file、あなたはそれが䜕であるかを知っおいたす。特別なこずは䜕も必芁ありたせん。䞀般的には䜿甚しおください。これは、unittestよりもはるかに䟿利です。







フィクスチャに぀いおもう少し。 pytestでは、さたざたなスコヌプのフィクスチャを䜜成するのは非垞に簡単です。デフォルトでは、フィクスチャは機胜レベルで䜜成されたす。これは、合栌したすべおのテストで呌び出されるこずを意味したす。぀たり、yieldたたはtearDownのようなものがある堎合、これは各テストの埌にも発生したす。



scope = 'module'を宣蚀するず、フィクスチャはモゞュヌルごずに1回実行されたす。デヌタベヌスを䞀床䜜成し、各テストの埌にすべおの移行をドロップアンドロヌルしたくないずしたす。



たた、フィクスチャではautouse = True匕数を指定するこずができ、芁求したかどうかに関係なくフィクスチャが呌び出されたす。このオプションは暗黙的なものであるため、絶察に䜿甚しないでください。たたは䜿甚する必芁がありたすが、非垞に泚意しおください。暗黙的なものは避けるのが最善です。







このコヌドを実行したした-䜕が起こったのか芋おみたしょう。フィクスチャに䟝存するテストのものがありたす。必芁に応じお䞀床䜿甚するず、毎回電話しおください。同時に、モゞュヌルレベルのフィクスチャが必芁なずきに䜿甚したら、私に電話しおください。初めおフィクスチャを呌び出したずきは、必芁に応じお䞀床䜿甚するず、毎回電話をかけお出力したすが、自動䜿甚のフィクスチャも呌び出されたした。気にしないため、垞に呌び出されたす。



2番目のテストは、同じフィクスチャに䟝存したす。モゞュヌルレベルであるため、必芁なずきに䞀床䜿甚するず2回目に呌び出すず、すでに1回呌び出されおおり、再床呌び出されるこずはありたせん。



さらに、この䟋から、あるテストではデヌタベヌスが必芁な堎合、別のテストでは䞀時ファむルが必芁な堎合に、pytestにはunittestで説明したような問題がないこずがわかりたす。それらを通垞どのように集玄するかは明確ではありたせん。これがpytestでのこの質問ぞの答えです。 2぀の噚具が枡された堎合、内郚に2぀の噚具がありたす。



玠晎らしい、ずおも快適で、問題ありたせん。フィクスチャは非垞に柔軟性があり、他のフィクスチャに䟝存する可胜性がありたす。これには矛盟はなく、pytest自䜓が正しい順序でそれらを呌び出したす。







実際、内郚では、他のフィクスチャからフィクスチャを継承し、スコヌプを倉えお、自動䜿甚せずに自動䜿甚するこずができたす。圌自身がそれらを正しい順序で配眮し、それらを呌び出したす。



ここに最初のテストがありたす。これはrare_dependency_for_test_oneに䟝存し、このフィクスチャは別のフィクスチャに䟝存したす。排気ガスで䜕が起こるか芋おみたしょう。







継承順に呌び出されるこずを確認したした。すべおの機胜レベルのフィクスチャがあるため、テストごずにすべお呌び出されたす。 2番目のテストはrare_dependencyに䟝存し、rare_dependencyはsome_common_dependencyに䟝存したす。排気口を芋るず、テストの前に2぀の噚具が呌び出されたこずがわかりたす。



Pytestには、すべおのフィクスチャを配眮できる特別な構成ファむルconftest.pyがあり、それを配眮するず䟿利です。通垞、人が他の人のコヌドを芋るずき、圌は通垞conftestのフィクスチャを調べに行きたす。



それは矩務ではありたせん。このファむルにのみ必芁なフィクスチャがあり、それが特定の狭い範囲で適甚可胜であり、別のファむルでは必芁ないこずが確実にわかっおいる堎合は、ファむルで宣蚀できたす。たたは、倚くのconftestを䜜成するず、それらはすべお異なるレベルで機胜したす。







pytestにある機胜に぀いお話したしょう。私が蚀ったように、テストをパラメヌタ化するこずは非垞に簡単です。ここでは、3぀のパラメヌタヌセットを持぀テストが衚瀺されたす。2぀の入力ず1぀の予期されるパラメヌタヌです。それらを関数匕数に枡し、入力に枡したものが期埅されるものず䞀臎するかどうかを確認したす。







それがどのように芋えるか芋おみたしょう。ここには3぀のテストがあるこずがわかりたす。぀たり、pytestはこれらが3぀のテストであるず考えおいたす。 2぀が通過し、1぀が萜ちたした。ここで䜕がいいの倱敗したテストに぀いおは、匕数が衚瀺され、どのパラメヌタヌセットで倱敗したかがわかりたす。



繰り返したすが、あなたが小さな機胜を持っおいお、パラメヌタ化が3ず蚀うずき、あなたはあなたの目で正確に䜕が萜ちたかを芋るかもしれたせん。しかし、パラメヌタに倚くのセットがある堎合、あなたはそれをあなたの目で芋るこずはできたせん。むしろ、あなたは芋るでしょう、しかしそれはあなたにずっお非垞に難しいでしょう。そしお、pytestがこのようにすべおを衚瀺するのは非垞に䟿利です-テストが倱敗した堎合はすぐにわかりたす。







パラメヌタ化は良いこずです。たた、䞀床テストを䜜成しおから、倚数のパラメヌタヌセットを実行する堎合、これは良い習慣です。同様のテスト甚に倚くのコヌドバリアントを䜜成するのではなく、䞀床テストを䜜成しおから、パラメヌタの倧芏暡なセットを䜜成するず、機胜したす。



pytestにはもっず䟿利なものがたくさんありたす。それらに぀いお話すず、明らかに講矩だけでは䞍十分なので、もう䞀床、ほんの少しだけ玹介したす。最初のテストでは、pytest.raisesを䜿甚しお、䟋倖が発生するこずを瀺したす。぀たり、この堎合、AssertionErrorが発生するず、テストに合栌したす。䟋倖がスロヌされるはずです。



2番目に䟿利なのはxfailです。テストを倱敗させるデコレヌタです。たくさんのテスト、たくさんのコヌドがあるずしたしょう。あなたは䜕かをリファクタリングしたした、テストは倱敗し始めたした。同時に、それは重芁ではないか、修理に非垞に費甚がかかるこずを理解しおいたす。そしお、あなたはこのようなものですさお、私はそれにデコレヌタを掛けたす、それは緑色に倉わりたす、私は埌でそれを修正したす。たたは、テストが氟濫し始めたずしたす。これは自分の良識ずの合意であるこずは明らかですが、必芁な堎合もありたす。さらに、この圢匏のxfailは、テストが倱敗したかどうかに関係なく緑色になりたす。それでもStrict = Trueパラメヌタヌに枡すこずができたす。そうするず、状況が少し異なり、pytestはテストが倱敗するのを埅ちたす。テストに合栌するず、゚ラヌメッセヌゞが返されたす。その逆も同様です。



もう1぀の䟿利なものはskipifです。テストを実行しないスキップがありたす。そしお、skipifがありたす。このデコレヌタにカヌ゜ルを合わせるず、特定の条件䞋でテストが実行されたせん。



この堎合、Macプラットフォヌムを䜿甚しおいる堎合は、䜕らかの理由でテストが倱敗するため、起動しないず曞かれおいたす。それは起こりたす。ただし、䞀般に、特定のプラットフォヌムでは垞に倱敗するプラットフォヌム固有のテストがありたす。次に、これは䟿利です。







はじめたしょうか。文字X、Sを芋たした。ここでXはxfail、S-はskipifを指したす。぀たり、pytestは、完党に倱敗したテストず実行したテストを瀺したすが、結果は確認したせん。







pytest自䜓にはさたざたな䟿利なオプションがありたす。もちろん、ここに衚瀺するこずはできたせん。ドキュメントで確認できたす。しかし、私はいく぀かに぀いおあなたに話したす。



これは䟿利な--collect-onlyオプションです。芋぀かったテストのリストが衚瀺されたす。オプション-k-テスト名によるフィルタリングがありたす。これは私のお気に入りのオプションの1぀です。1぀のテストが倱敗した堎合、特に耇雑で修正方法がわからない堎合は、フィルタリングしお実行したす。



あなたは時間を節玄したいず思っおおり、おそらく他の15のテストを実行するのは楜しいこずではありたせん。クラッシュするテストを実行し、修正しお次に進みたす。



非垞に優れたオプション-sもあり、テストでstdoutおよびstderrからの出力を有効にしたす。デフォルトでは、pytestは倱敗したテストに察しおのみstdoutずstderrを出力したす。ただし、通垞はデバッグの段階で、テストで䜕かを出力したいが、テストが倱敗するかどうかわからない堎合がありたす。萜ちないかもしれたせんが、テスト自䜓で䜕が来お出力されるかを確認したいず思いたす。次に、-sを指定しお実行するず、必芁なものが衚瀺されたす。



-vは暙準の冗長オプションであり、冗長性を高めたす。



--lf、-last-failedは、最埌の実行で倱敗したテストのみを再起動できるオプションです。 --sw、-stepwiseも-kのような䟿利な関数です。テストを順番に修埩する堎合は、-stepwiseを䜿甚しお実行するず、緑色のテストが実行され、倱敗したテストが怜出されるずすぐに停止したす。たた、-swを再床実行するず、クラッシュしたこのテストから始たりたす。再び萜䞋した堎合は再び停止し、萜䞋しなかった堎合は次の萜䞋たで移動したす。





スラむドからのリンク



pytestには、メむンの構成ファむルpytest.iniがありたす。その䞭で、pytestのデフォルトの動䜜を倉曎できたす。ここでは、構成ファむルによくあるオプションを瀺したした。



テストパスは、pytestがテストを怜玢するパスです。 addoptsは、起動時にコマンドラむンに远加されるものです。ここでは、addoptsにflake8ずcoverageプラグむンを远加したした。少し埌で芋おいきたす。





スラむドからのリンク



pytestにはさたざたなプラグむンがありたす。繰り返しになりたすが、どこでも䜿甚されおいるものを曞きたした。 flake8はリンタヌであり、カバレッゞはテストによるコヌドカバレッゞです。次に、pytest-flask、pytest-django、pytest-twisted、pytest-tornadoなどの特定のフレヌムワヌクでの䜜業を容易にするプラグむンのセット党䜓がありたす。おそらく他に䜕かがありたす。



xdistプラグむンは、テストを䞊行しお実行する堎合に䜿甚されたす。タむムアりトプラグむンを䜿甚するず、テストの実行時間を制限できたす。これは䟿利です。テストでタむムアりトデコレヌタをハングさせ、テストに時間がかかる堎合は倱敗したす。







芋おみたしょう。 pytest.iniにcoverageずflake8を远加したした。カバレッゞは私にレポヌトを䞎えたした、私はそこにテストを含むファむルを持っおいたす



、それから䜕かが呌び出されたせんでした、しかしそれは倧䞈倫です:)これはk_stat.pyファむルです、それは5぀ものステヌトメントを含みたす。これは、5行のコヌドずほが同じです。カバレッゞは100ですが、それは私のファむルが非垞に小さいためです。



実際、カバレッゞは通垞100ではなく、さらに、決しお達成されるべきではありたせん。䞻芳的には、60〜70のテストカバレッゞで十分であり、正垞に機胜しおいるようです。



カバレッゞは、100であっおも、自分が優れおいるずは蚀えないほどの指暙です。このコヌドを呌び出したずいう事実は、䜕かをチェックしたこずを意味するものではありたせん。最埌にassertTrueず曞くこずもできたす。 100のテストカバレッゞにはフェヌゞングずロボットがありたすが、人々はそれを行う必芁はありたせん。



pytest.iniで、もう1぀のプラグむンを接続したした。ここに--flake8がありたす。これは私のスタむル゚ラヌを瀺すリンタヌであり、PEP8ではなくpyflakesからのものです。







ここの排気ガスには、PEP8たたはpyflakesの゚ラヌ番号が曞かれおいたす。䞀般的に、すべおが明確です。行が長すぎたす。再定矩するには2行の空癜行が必芁であり、ファむルの最埌に空癜行が必芁です。最埌に、CitizenImportは私には䜿甚されおいないず曞かれおいたす。䞀般に、リンタヌを䜿甚するず、重倧な゚ラヌやコヌド蚭蚈の゚ラヌを怜出できたす。







タむムアりトプラグむンに぀いおはすでに説明したした。これにより、テストの実行時間を制限できたす。䞀郚のパフォヌマンステストでは、実行時間が重芁です。そしお、time.timeずtimeitを䜿甚しおテスト内で制限できたす。たたは、タむムアりトプラグむンを䜿甚したす。これも非垞に䟿利です。テストが機胜しすぎる堎合は、cProfileなど、さたざたな方法でプロファむルを䜜成できたすが、Yuraは講矩でこれに぀いお説明したす。







IDEを䜿甚しおいお、補助ツヌルを䜿甚する䟡倀がある堎合は、ここに特にPyCharmがあり、テストはIDEから盎接実行するのが非垞に簡単です。







モックに぀いお話すこずは残っおいたす。モゞュヌルAがあり、それをテストしたいのですが、テストしたくないモゞュヌルが他にもあるずしたす。 1぀はネットワヌクに接続し、もう1぀はデヌタベヌスに接続し、3぀目はたったく煩わしくない単玔なモゞュヌルです。そのような堎合、モックは私たちを助けたす。繰り返したすが、統合テストを䜜成する堎合は、テストデヌタベヌスを起動し、テストクラむアントを䜜成する可胜性が高く、それでも問題ありたせん。これは単なる統合テストです。



1぀のピヌスだけをテストしたいずきにナニットテストを実行したい堎合がありたす。次に、モックが必芁です。







モックは、実際のオブゞェクトを眮き換えるために䜿甚できるオブゞェクトのコレクションです。メ゜ッドや属性を呌び出すず、モックも返されたす。







この䟋では、単玔なモゞュヌルがありたす。そのたたにしお、もっず耇雑なものをモックに眮き換えたす。これがどのように機胜するかを芋おいきたす。







ここにはっきりず瀺されおいたす。私たちはそれを茞入したした、私たちはmがモックであるず蚀いたす。モックを呌び戻した。圌らは、mには方法fがあるず蚀った。モックを呌び戻した。圌らは、mがis_alive属性であるず蚀いたした。玠晎らしい、別のモックが戻っおきたした。そしお、mずfが䞀床呌び出されるこずがわかりたす。぀たり、これは非垞にトリッキヌなオブゞェクトであり、その䞭でgetattrメ゜ッドが曞き盎されたす。







より明確な䟋を芋おみたしょう。 AliveCheckerがあるずしたしょう。圌はある皮のhttp_sessionを䜿甚し、タヌゲットが必芁であり、受け取ったものに応じおTrueたたはfalseを返すdo_check関数を持っおいたす200たたは200ではありたせん。これは少し人工的な䟋です。しかし、do_checkの内郚で耇雑なロゞックを完成させるこずができるず仮定したす。



セッションに぀いお䜕もテストしたくない、getメ゜ッドに぀いお䜕も知りたくないずしたしょう。 do_checkのみをテストしたす。よし、テストしおみよう。







あなたはこのようにそれを行うこずができたす。 http_sessionをモックしたす。ここではpseudo_clientず呌ばれたす。圌女のgetメ゜ッドをモックしたす。getは200を返すモックであるず蚀いたす。起動し、これからAliveCheckerを䜜成し、起動したす。このテストは機胜したす。



さらに、getが䞀床呌び出され、蚘述されたものずたったく同じ匕数で呌び出されたこずを確認したしょう。぀たり、セッションが䜕であるか、たたはそのメ゜ッドが䜕であるかを䜕も知らずにdo_checkを呌び出したした。ただ凍らせただけです。私たちが知っおいる唯䞀のこずは、それが200を返したこず







です。別の䟋。それは前のものず非垞に䌌おいたす。ここでの唯䞀のものは、return_valueではなくside_effectです。しかし、それはモックが行うこずです。この堎合、䟋倖がスロヌされたす。アサヌト行は、AliveChecker.do_checkではなくアサヌトするように倉曎されたした。぀たり、チェックに合栌しないこずがわかりたす。



これらは、䞊から䜕が入ったのか、このクラスに入ったのかに぀いお䜕も知らずにdo_check関数をテストする方法の2぀の䟋です。







もちろん、この䟋は人為的なものに芋えたす。200であるかどうかにかかわらず、チェックが最小限のロゞックである理由は完党には明らかではありたせん。しかし、リタヌンコヌドに応じおトリッキヌなこずをするこずを想像しおみたしょう。そしお、そのようなテストははるかに意味があるように芋え始めたす。 200が来るのを芋お、凊理ロゞックをチェックしたす。 200でない堎合-同じ。







ラむブラリにモックでパッチを適甚するこずもできたす。すでにラむブラリがあり、その䞭の䜕かを倉曎する必芁があるずしたす。これが䟋です。サむンにパッチを適甚したした。今、圌はい぀もデュヌスを返したす。優れた。



たた、mが2回​​呌び出されおいるこずもわかりたす。もちろん、モックは、モックするメ゜ッドの内郚APIに぀いお䜕も知りたせん。たた、䞀般に、それらず䞀臎する必芁はありたせん。しかし、モックを䜿甚するず、䜕を呌び出したか、䜕回、どの匕数で呌び出したかを確認できたす。この意味で、コヌドをテストするのに圹立ちたす。







モゞュヌルが1぀ず巚倧なモックしかない堎合は譊告したいず思いたす。すべおに合理的にアプロヌチしおください。簡単なものがある堎合は、濡らさないでください。テストにモックが倚ければ倚いほど、珟実から離れおしたいたす。APIが䞀臎しない可胜性があり、䞀般に、これはテストしおいるものず正確には䞀臎したせん。あなたは必芁なしにすべおを浞す必芁はありたせん。プロセスにむンテリゞェントにアプロヌチしたす。







継続的な統合に぀いおの最埌の小さな郚分が残っおいたす。ペットプロゞェクトを単独で開発しおいる堎合は、ロヌカルでテストを実行できたすが、倧したこずではありたせん。



プロゞェクトが成長し、耇数の開発者がプロ​​ゞェクトに参加するずすぐに、プロゞェクトは機胜しなくなりたす。たず、半分はロヌカルでテストを実行したせん。第二に、圌らは圌らのバヌゞョンでそれらを実行したす。どこかで衝突が起こり、すべおが絶えず厩壊したす。



そのために、継続的な統合がありたす。これは、候補者を䞻流に迅速に泚入するこずを含む開発手法です。しかし同時に、圌らは特別なシステムである皮の自動組み立おたたは自動テストを経なければなりたせん。リポゞトリにコヌドがあり、メむンプロゞェクトブランチにマヌゞするコミットがありたす。これらのコミットでは、テストは特別なシステムで合栌したす。テストが緑色の堎合は、コミットが単独で泚入されるか、コミットを泚入する機䌚がありたす。



もちろん、そのようなスキヌムには、すべおだけでなく、欠点もありたす。少なくずも、CIが無料になるずいう事実ではなく、远加のハヌドりェアが必芁です。しかし、倧䌁業ではなく、倚かれ少なかれ倧䌁業では、CIなしではどこにも行けたせん。







䟋ずしお、CIの1぀であるTeamCityのスクリヌンショット。組み立おがあり、無事に完成したした。それに倚くの倉曎がありたした、それはそのようなそしおそのような時にそのようなそしおそのような゚ヌゞェントで立ち䞊げられたした。これは、すべおが良奜で、泚入できる堎合の䟋です。



倚くの異なるCIシステムがありたす。興味があれば、リストを䜜成したした。AppVeyor、Jenkins、Travis、CircleCI、GoCD、Buildbotです。ありがずう。






Pythonに関するビデオコヌスの他の講矩は、Habréの投皿にありたす。



All Articles