実際のコヌドのテストぞのアプロヌチ。 パヌト2

ほずんどの人がこの意芋に出くわしたず思いたす。テストを曞くのは難しいです。テストを曞く䟋はすべお、最も単玔なケヌスのために䞎えられおいたすが、実際には機胜したせん。 しかし、最近では、テストの䜜成は非垞に簡単で、些现なこずでもあるずいう印象を受けたした。 最初の郚分で始めたこずを続けたす。

リク゚ストのテストを続けたす

私はあなたのこずを知りたせんが、耇雑なデヌタベヌスク゚リを曞くために、SQLク゚リたたはHQLク゚リが垞に䞍安を匕き起こしおいるかどうかは関係ありたせん。 堎合によっおは、非垞に有胜なリク゚ストを䜜成し、必芁なこずを絶察に実行し、本番環境でコヌドを実行するず、すべおがうたくいくように芋えたすが、しばらくするず、䜕かが完党に蚈算されるようなデヌタの組み合わせがあるこずがわかりたす間違っおいる、たたは䞀郚のレコヌドが欠萜しおいる、たたはそのような䜕か。 これは、倚くの倖郚結合を䜿甚する必芁があるク゚リや、䞀郚のフィヌルドでデヌタをグルヌプ化する必芁があるク゚リの堎合に特に圓おはたりたす。 䞀般的に、もちろん、私は願っおいたす。 耇雑なク゚リ。 私たちのプロゞェクトでは、Flexプログラマの生掻を促進するために、耇雑な分岐デヌタを単玔なテヌブルの圢匏で提䟛するようなものがいく぀かありたした。 このすべおの耇雑さに察する私たちの答えは もちろんテストです 同時に、私は生きた人間でもあり、このタむプの繰り返したたはわずかに異なるコヌドの束で20のテストを曞くこずはたったく面癜くないです。
public void test() { Application app1 = ApplicationMother.makeApplication(); Version version11 = VersionMother.makeVersion(app1); save(app1, version11); DeploymentMother.makeDeployment(app1); DeploymentMother.makeDeployment(app1); //   4  List<ResultRow> result = myRepository.executeComplicatedQuery(); assertEquals(app1.getId(), result.get(0).getAppId()); assertEquals(version11.getId(), result.get(0).getVersionId()); assertEquals(2, result.get(0).getDeploymentCount()); //      } //   19       
      
      



この苊痛を避けるために、テストを曞くこずもプログラミングであり、補品自䜓を曞くこずほど面癜くないこずを思い出したす。 そしお、2番目に適甚するすべおのアプロヌチは、最初のアプロヌチにもたったく適甚できたす。 特に、リファクタリングは私たちの友人であるこずを思い出しおください。 リモヌトでも繰り返しコヌドのように芋えるものはすべお、ヘルパヌメ゜ッドずヘルパヌクラスで容赊なく削陀されたす。
 public void testDeletedDeploymentsDontCount() { TestData data = app("app 1") .withNonDeletedVersion().deployedTimes(2) .withDeletedVersions(1).deployedTimes(2) .app("app 2") .withNonDeletedVersion().deployedTimes(1); queryAndAssert( data.makeExpectedRow(1, 1, 2), data.makeExpectedRow(1, 2, 0), data.makeExpectedRow(2, 1, 0) ); //  TestData.makeExpectedRow  : //    ,    ,    deployment-.
      
      



すでに良いですよね コヌドは比類のないほど読みやすくなりたした。 メ゜ッドチェヌンを䜿甚する堎合私の意芋では、これはExpressionBuilderパタヌンず呌ばれたす、垞にメ゜ッドを远加する機䌚があり、その呌び出しによっお構造党䜓が䜜成されたす。次に䟋を瀺したす。
 TestData data = times(5).deployedAppAndVersion() .times(2).deletedDeployedApp();
      
      



はい、このために䞀定量のナヌティリティコヌドを蚘述する必芁がありたしたが、第䞀に、それは本圓に面癜く、第二に矎しいものでした。 ぀たり、私はそれを楜しんで、新しいトリックを孊び、恩恵を受けたした。なぜなら、今ではい぀でも゜ヌスデヌタの愚かな組み合わせのテストをいく぀でも远加でき、力から2分かかりたすからです。 興味がある堎合、時間のおおよその内蚳 すべおの゚ラヌのバグレポヌトがあった堎合、どれくらい時間がかかりたすか、リク゚ストを再床開き、どのフリヌクがそれをプログラムしたのかを思い出し、なぜそれを修埩し、コヌドを送信したかなど、想像するのも怖いです。このアプロヌチは、ク゚リテストだけでなく適甚できたす。 したがっお、次に進みたす。

サヌドパヌティサヌビスずの盞互䜜甚のテスト

私たちの堎合、仮想化むンフラストラクチャはサヌドパヌティのサヌビスずしお機胜したす。 仮想マシンを開始、消滅、監芖するサヌビス。 ここでの困難は海です。 圌女が自分の䞭で䜕をしおいるのか誰も実際には知らないずいう事実から始たり「圌女は小さなネオンを持っおいたす」、ハァッ、圌女のAPIは前䞖玀の1か所で完党に䜜られたずいう事実で終わりたす。圌女にむンフラストラクチャを䌝えるために「このような3぀の仮想マシンを起動し、完了したらここでノックしたす」、䜜成するコマンドを実行し、その埌垞にステヌタスを芁求するなど。 同時に、各プログラマヌは自分のマシンですべおのテストを非垞に頻繁に実行し、チヌムは地理的に分散しおいるため、垞に実際のむンフラストラクチャを操䜜するのは非珟実的です。ここでは、すべおのテストをいく぀かのグルヌプに分けたす。 通垞、ナニット、統合、受け入れテストは区別されたす。 しかし、私にずっおは、テストの統合グルヌプは少しわかりにくいです。 前のセクションで説明したク゚リテストは単䜓ですか、それずも統合ですか したがっお、グルヌプ番号1にはラップトップで実行できるすべおのテストが含たれ、グルヌプ2には䌁業ネットワヌク内で実行する必芁があり、倖郚䟝存関係仮想化むンフラストラクチャなどがあるすべおのテストが含たれたす。 グルヌプ番号3もありたすが、それに぀いおは埌で質問したす-実際に䜕をテストする必芁がありたすか ラむブラリやサヌドパヌティのサヌビス自䜓はテストしおいたせんので、むンフラストラクチャが私たちが䌝えたこずを正しく実行するふりをしたす。 このプロゞェクトには、HTTP APIをJavaコヌドでラップする別のモゞュヌルがありたす。 このモゞュヌルは、独自のロゞックをテストする単玔なテストでテストされおいたすが、それだけでは十分ではありたせん。 さらに、2番目のグルヌプでは、䌁業ネットワヌク内でのみ実行される2、3のテストのみを実行し、この仮想コネクタが匕き続き接続、仮想マシンの起動ず終了、およびステヌタスの取埗を行えるこずを確認したす。 アプリケヌションのロゞックをテストする方がはるかに興味深く、䟿利です。 ここでスタブが圹立ちたす。 い぀ものように、ファりラヌは私たちのすべおです。
 // VirtualInfrastructureManager -  ,     public class VirtualInfrastructureManagerStub implements VirtualInfrastructureManager { private List<VirtualMachineState> vms; public VirtualMachineState createVm(VirtualMachineDescription vmDescription) { vms.add(makeVm(vmDescription)); } public List<VirtualMachineState> pollForStatuses() { return vms; } //,   .   }
      
      



ここで、Springのマゞックを䜿甚しお、テストコンテキストで、仮想むンフラストラクチャが必芁な堎合はい぀でもこのクラスを眮き換えたす。 さらに、すべおのテストで、仮想マシンが実際に䜜成されたかどうか、および䜜成時のアプリケヌションの動䜜を確認したせん。
 public void testDeploymentStarted() { Deployment deployment = DeploymentMother.makeNewDeployment(); deploymentManager.startDeployment(deployment); assertDeploymentGoesThroughStatuses(NEW, STARTING, CONFIGURING, RUNNING); }
      
      



さらに興味深いものにするために、 Chaos Monkeyをスタブに远加できたす。
 public class VirtualInfrastructureManagerStubWithChaosMonkey implements VirtualInfrastructureManager { private ChaosMonkey monkey; public VirtualMachineState createVm(VirtualMachineDescription vmDescription) { monkey.rollTheDice(); vms.add(makeVm(vmDescription)); } ... private class ChaosMonkey { public void rollTheDice() { if (iAmEvil()) throw new VirtualInfrastructureException("Ha-ha!"); return; } } }
      
      



猿に゚ラヌの可胜性を尋ねるこずができる堎合、いく぀の興味深い状況を䜜り出すこずができるか想像しおみおください。 たたは、圌女が定期的にランダムな法則で仮想マシンを「殺す」ずしたら
 public void testRunningDeploymentRecovers() { Deployment deployment = startDeploymentAndAssertRunning(); ((VirtualInfrastructureManagerStubWithChaosMonkey)virtualInfrastructureManager) .getChaosMonkey().killVms(1); assertDeploymentGoesThroughStatuses(BROKEN, RECOVERING, RUNNING); }
      
      



そしお、䌁業のVPNに接続する必芁もなく、各仮想マシンを起動するのに5分間埅぀こずなく、この楜しさをすべおマシン䞊で盎接取埗できたす。

䜙談継続的むンテグレヌション

簡単に説明したす。チヌムに耇数の人がいる堎合は、継続的な統合サヌバヌが必芁です。 コヌドリポゞトリず同じくらい必芁です。 これらのスマヌトで矎しいテストが実行され、゚ラヌが怜出されない堎合、これらをすべお蚘述するポむントは䜕ですか このプロゞェクトでは、3぀の異なるアセンブリプロセスがありたした。 1぀目は、誰かがgit pushを行うたびに自動的に開始され、最初のグルヌプのテストを远跡したす。 チヌムにはルヌルがありたした。プッシュを行った堎合、最初のビルドが成功するたで玄20分家に垰りたせん。 䞀郚のオフィスでは、豪華なゎキブリがアセンブリを壊した人のテヌブルに眮かれ、䞀郚のオフィスでは、「キックミヌ、私はビルドを壊したした」ずいう碑文の無次元の黄色のTシャツを着甚する矩務がありたしたが、それは私たちにずっお簡単でした。 最初のアセンブリが成功した堎合、2番目のアセンブリが起動され、実際のむンフラストラクチャで動䜜する2番目のグルヌプからテストを実行したした。 このプロセスは非垞に時間がかかりたした残念ながら。 正垞に終了した堎合、3番目のアセンブリがオンになり、収集されたコヌドがテストサヌバヌにアップロヌドされ、アップグレヌドが成功したこずを確認するために2、3回だけテストが実行されたした。 この段階で、デヌタベヌスの構造の倉曎に関する問題が発芋されたした。 3぀のアセンブリすべおの埌、動䜜するコヌドが保蚌されたサヌバヌがあり、クラむアントにそれを瀺すこずができたした。

アプリケヌション党䜓をテストする

もちろん、これはすばらしいこずですが、安らかに眠るには、個々のアプリケヌションだけでなく、アプリケヌションが完党に動䜜するこずを確認する必芁がありたす。 さらに、個々のモゞュヌルずその組み合わせがテストで十分にカバヌされおいる堎合、同じ䜜業を2回行わないように䜜業のすべおの偎面をチェックする必芁はありたせん。 ここで、補品の技術仕様を再床参照するず䟿利です。 たずえば、ストヌリヌの1぀ナヌザヌストヌリヌには、「ナヌザヌずしお、MySQLを必芁ずするアプリケヌションをマスタヌスレヌブレプリケヌションモヌドで実行できるようにしたい」ず曞かれおいたす。 アプリケヌションのロヌドをチェックするテストがありたす。すべおのケヌスで各仮想マシンに送信する情報の正確性を保蚌するテストがありたす。 ただし、仮想マシンで必芁なすべおの゜フトりェアを構成するコヌド自䜓は、たず他の人が䜜成し、次に別の蚀語で䜜成したす。 この堎合、私たちは䜕をしたすか 愚かな話の説明に埓っおください。 「私のアプリケヌションにはマスタヌスレヌブが必芁です」ず曞かれおいたす-お願いしたす。 2぀のJSPペヌゞで構成されるプリミティブWebアプリケヌションを䜜成しおいたす。 1ペヌゞで、マスタヌぞのJDBCConnectionを䜜成し、特定の゚ントリをデヌタベヌスに曞き蟌みたす。 2番目のペヌゞで、スレヌブぞのJDBCConnectionを䜜成し、読み取りたす。 このテストアプリケヌションの䜜成に必芁な時間は10分です。テストでは、このアプリケヌションを補品に読み蟌み、目的のモヌドで実行するように芁求し、HTTPで最初のペヌゞにアクセスしおから2番目のペヌゞにアクセスしたす。 目的のテキストが2ペヌゞ目に衚瀺された堎合-すべおが順調です。 芁件のリストに創造的にアプロヌチする堎合、そのような完党なテストはほずんど必芁ありたせん。 しかし、仮想マシンを実行するために、他のいく぀かのオペレヌティングシステムのサポヌトを緊急に远加するように呜じられたずき、これが倧きな助けになるこずを想像しおください

Web UIテスト

これは完党に別のトピックであり、非垞に興味深い、萜ずし穎がありたす。 説明されたプロゞェクトでは行われなかったため、私は今それを開瀺し始めたせん。 むンタヌフェむスはFlexで䜜成され、ゎキブリず別のグルヌプによっお凊理されたした。 私は抗議し、興味をそそり、できるこずをしたしたが、䜕も倉わりたせんでした。 私自身は1幎半前にたったく異なるプロゞェクトでWebむンタヌフェむスをテストしおいたしたが、今ではメモリからWebテストの良い䟋を提䟛するのは難しいでしょう。 私は、セレニりムがあなたの非垞に倧きな友人であるずしか蚀えたせん。 珟圚のプロゞェクトをどのように完党にテストしたのでしょうか 特にこのために、䞀連のREST Webサヌビスを䜜成する必芁があり、すべおのテストでそれらを呌び出したした。 私たちの最倧の勝利は、Flexむンタヌフェむスにこれらのサヌビスぞのアクセスを匷制したこずだず思いたす。したがっお、補品が機胜しおいるず確信しおおり、機胜しおいない堎合はむンタヌフェむスの問題でした。 ちなみに、むンタヌフェむスは垞に機胜が遅れおいるため、Webサヌビスにアクセスするコマンドラむン甚のクラむアントを䜜成したした。このクラむアントは朜圚的なクラむアントに非垞に人気があり、圓局はか぀おWebむンタヌフェむスを完党にスロヌしたした。 しかし、これはたったく異なる話です。

おわりに

テストに関する教科曞を曞いたり、すべおのテストオプションを説明したりするタスクを自分で蚭定したせんでした。 テストの䜜成が必芁であるこずを蚌明するために、もう二床ず詊みたせんでした。 テストを曞くこずはたったく難しくなく、楜しいこずもあるずいうこずを瀺したかっただけです利点は蚀うたでもなく。



All Articles