手間もコストもかかるGUIのテストはどうすれば自動化できるのか
12月 02, 2024 by Qt Group 日本オフィス | Comments
MONOist 2024年5月21日掲載記事:手間もコストもかかるGUIのテストはどうすれば自動化できるのか
GUIを搭載するアプリケーションや機器の市場が拡大し、GUIのテストの効率化がソフトウェア開発
者の課題になっている。そこで役立つのが、GUIテストの自動化が可能なQt Groupの「Squish」
(スクイッシュ)だ。
GUIテストの自動化というトレンド
GUIテストに手間がかかるのは、GUIはユーザーの操作に伴って処理が進むイベント駆動型プログラムであるためだ。単体テストであればともかく、複数の機能を扱う結合テストやシステム全体を対象とするシステムテストには人手による操作が不可欠だ。これらをある程度自動化しない限り、GUIテストの負荷が大きくのしかかり続けることになる。
ここでのポイントは「ある程度」というところだ。GUIテストをいきなり完全に自動化しようとすると、その環境の構築に手間と時間がかかってしまう。自動化しやすいプロセスからテスト環境を構築し、それをベースに自動化の割合を増やすのが効果的だ。Qt Group ソリューションエンジニアリング部 ソリューションエンジニアの坂本強氏は「ある調査によれば、テストを50%自動化した程度でも、テストサイクルの短縮やカバレッジの向上、開発の初期段階での問題の特定などに大きな効果が得られるという結果が出ています。この結果からも、テストの自動化はできる範囲から始めて、段階的に自動化の範囲を広げるのが効果的です」と語る。
GUIテストを自動化する効果は大きい。カーナビゲーションや位置情報ソリューションを提供するTelenavは、夜間に約800種類のGUIテストを自動で行っている。開発者は翌日にテストレポートを確認してプログラムを修正する。もちろん、800種類ものテストを手動で行う手間を削減できることの効果は言うまでもない。
GNSS受信機を手掛けるトプコンは、オープンソースのCI/CD(継続的インテグレーション/継続的デリバリー)環境であるJenkinsと組み合わせて1000種類以上のGUIテストを自動化している。昨今はファームウェアのアップデートによって製品の機能を向上させるのが一般的になりつつある。そのためには新しいファームウェアが不具合を起さないことを確認するリグレッション(回帰)テストが必須だ。これを自動化することでメンテナンスコストを大幅に削減できる。
GUIテストを自動化する「Squish」
これら2社のGUIテスト自動化に活用されているのがQt Groupの「Squish」だ。QtGroupは広く利用されているGUIフレームワーク「Qt」で知られているが、SquishはQtのみならずWindowsやmacOS、Android、iOS、Java、Webなどで動作するGUI自動テスト環境を提供する。複数のプラットフォームで利用されるGUIに同一のツールを適用できるのがSquishのメリットであり、Qtで作成されたアプリケーションであればテストスクリプトもそのまま利用できる。
GUIテストのテストケースは、PythonやJavaScript、Perl、Ruby/Tkといった汎用(はんよう)のスクリプト言語で記述できる。GUIテストは「人手による操作」が必要なことが課題だが、Squishには一度人手で行った操作からテストケースを自動生成するレコーディング機能も用意されている。
GUIテストを自動化する際は「アプリケーションが正しく動作しているか否か」をツールが判断できる必要がある。そのために画像ベースの比較やOCRでの文字認識、ビジュアル検証など、複数の手法が用意されている。また、コードカバレッジツールを併用すると、テスト項目の検証やテストの妥当性を確認することができるので、無駄なテストを抑制できる。
テストターゲットが手元にない状態でのリモートテストも可能だ。複数のテストの実施や複数のターゲットへの分散実行、レポートの生成といった分散型バッチテストもできる。トプコンの事例で挙げたJenkinsをはじめとするCI/CD環境や統合テスト環境との連携に必要なプラグインも提供されている。
坂本氏は「Squishの豊富な機能を活用して、早いタイミングで簡単にできる範囲からGUIテストを自動化すれば、テスト全体を効率化できます。それに伴ってプログラム品質の改善などの効果を得られるでしょう」と強調する。
BDDテストのサポートでブラックボックステストにも対応
ここまで説明してきたSquishの機能は、「実装されたGUIやその先の処理が正しく設計通りの振る舞いをするかどうか」を確認するホワイトボックステストに利用できる。これはこれで重要なテストだ。だが、システムテストともなると設計に基づく内部構造を考慮せず、入力と出力だけに着目するブラックボックステストも必要になってくる。そこで役立つのが、SquishがサポートしているBDD(ビヘイビア駆動開発)テストだ。
BDDテストは、アプリケーションに期待される振る舞い(ビヘイビア)を記述するストーリーを中心としたテスト手法だ。テストの作成や記録、保守やデバッグなどは全てGherkin記法を利用したスクリプト言語で行える。
下の図はBDDテストの記述例だ。「カプチーノを選択してコーヒーをいれる」という流れについて、人間が理解しやすい形でシナリオを記述できることが分かる。BDDテストでは、このシナリオに沿って生成されたテストスクリプトを用いてテストする。

BDDテストのメリットは、テストシナリオの作成や修正をプログラマーが行う必要がないことだ。シナリオは日本語で記述することも可能であり、その記述内容はあくまでアプリケーションの操作であってプログラムなどの内部構造は関係しない。そのため、シナリオの作成/修正は製品の企画担当者やデザイナーなどでも可能だ。
BDDテストのシナリオは、アプリケーションの要求仕様をそのままテスト内容として記述しているとも言える。「つまり、BDDテストは要求仕様の検証にもつながり、仕様の漏れや抜けも確認できることになります」(坂本氏)
Cocoを利用したカバレッジ分析とTest Centerによる統合管理
ソフトウェアテストでは、テストシナリオがプログラムのどの程度の機能をカバーしているのか、重要な領域をどの程度テストしているのかなどを示すカバレッジが有効な指標になる。強力なテストツールであるSquishのみならず、Qt Groupはカバレッジを分析するツールも提供している。
カバレッジ分析は、始めるのが早ければ早いほど効果が高い。「テストの抜けあるいはテストの重複を後に発見して対応するよりも、早い段階で発見して対処する方がエンジニアリングコストの低減につながります」(坂本氏)。自動車や産業機器など、機能安全規格への準拠が求められるアプリケーションではカバレッジ分析が要件として義務付けられていることもある。
このカバレッジ分析用にQt Groupが提供しているのが「Coco」(ココ)だ。Cocoは、C、C++、C#、Tcl、SystemC、Qt用のユーザーインタフェース記述であるQMLで開発されたソースコードをビルドする際に、カバレッジ分析用のコードを自動挿入してカバレッジ分析を行う。
Cocoはカバレッジ分析の実行、記録、レポート作成の他、さまざまなテストフレームワークやCI/CD環境と連携可能だ。関数プロファイラを利用したパフォーマンスの計測やブラックボックステスト機能もある。
SquishやCocoで得られた結果を統合管理できるのが「Test Center」(テストセンター)だ。テスト結果の一元管理やトレーサビリティーの提供、相関分析、レポート生成などをまとめて行える。複数の開発者がGitなどのソース管理システムを併用して行う大規模システム開発では、作成されるレポートの量も膨大になる。Test Centerがあれば、レポートを容易に管理できる。また、Webブラウザ対応のデータベースとして構築されるので、いつでもどのデバイスからでも簡単にアクセスできる。
昨今のGUIの急速な普及やマルチプラットフォーム対応などで、GUIの開発工数やエンジニアリングコストは増加傾向にある。GUI開発を効率化するため有力なツールとして、GUIのテストに役立つSquish、Coco、Test Centerといったツールを検討してみてはいかがだろうか。
Blog Topics:
Comments
Subscribe to our newsletter
Subscribe Newsletter
Try Qt 6.8 Now!
Download the latest release here: www.qt.io/download.
Qt 6.8 release focuses on technology trends like spatial computing & XR, complex data visualization in 2D & 3D, and ARM-based development for desktop.
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.
Cool, would be nice to see someone make it works with cmake :) (not me, I am infinitely too lazy)
How hard would it be to make this same program work with any set of unit tests? Say I want to use the same pretty interface for the unit tests on my own OSS project. Can I cherry-pick this program and fill it in with my list of auto-tests, or is it not ready for that yet?
I'm as curious as Nathan: can this be used for generic autotests?
@Nathan, @razvanpetru
Yes I thought about that, and it would not require a lot of modifications. It currently parses the auto-tests project file (auto.pro in tests/auto), so it could just take any .pro file as input instead. I will definitely look into that.
I wonder, how does this handle the GUI unit tests? Some months ago, I started work on my own test running tool (http://gitorious.org/qt-com...) as part of the community integration project I was working on at the time (http://blog.rburchell.com/2...), but one of the stumbling blocks I got stuck on at the time was that reliably creating and tearing down a test instance (dbus, GUI with no WM/styles, etc) was a lot of work.
I guess I'm going to have to look into this again sometime soon as I want to start revisiting the community integration stuff.
I'd also just like to add: great news! This is exactly the sort of thing I hope to see a lot more of after writing about the frustrations that many are feeling with trying to contribute to Qt (see http://blog.rburchell.com/2...).
@Robin
It is a bit problematic for GUI tests indeed... For now you can't do anything at the same time for these tests. I'm not sure what to do about that...
@Siddharth
Thank Shane and Liang for that :)
@Rohan
Like Bjørn Erik said, the idea is just to have some helper tool to automate and speed up things so I don't think your first point is relevant.
For your second point you are right, ideally the tool should query the list of tests from some server, but then it closes the door to running external auto-tests. Or then we need a different mode for Qt auto-tests and external auto-tests...
Is this blog entry linked from our contribution model help pages? :)
+2 kudo points for making it work on Symbian. Thank you.
I have a couple of suggestions:
First, the test running logic shouldn't be implemented in this tool, because then it can't be reused in automated systems. e.g. this tool probably runs the tests in a slightly different way than the Qt Continuous Integration system itself does - especially for the more complex things such as running of autotests on symbian devices.
Second, the parsing of test definitions from the .pro files probably shouldn't be done here, because it's more error prone than proper build system integration - this tool might have a different idea about what is/isn't a testcase than other systems which are trying to run the tests. The build system knows `make check' and ideally that's the one canonical way to determine what is and isn't a testcase.
@ Rohan
I believe Yoann wrote this nifty tool to make it easier to run Qt auto tests (tests/auto/*). His goal was clearly not to make a swiss army auto tester tool supporting every single use case without being good at anything. To put it simple; it is a replacement for the following workflow:
cd $class ./tst_$class cd .. cd $anotherClass ./tst_$anotherClass cd ..
... it even supports running tests in parallel :-)
@Yoann Lopes
A cross platform solution is... yeah, going to be difficult, if possible at all. The solution I settled on (as I only run Linux) at the time, was to run an Xvfb instance via QProcess. I'm happy to help contribute to make that happen if it's something you'd like to see.
However...
I noticed that some tests don't seem to like Xvfb (unreliable failures), using Xephyr instead made tests pass, but meant that I had to have an annoying window hovering around. Never figured out why. :)
That's a really nice (and fancy looking) tool. Having a test suite for making sure that nothing is broken by your own changes is a must.
What I'd like to see is something like this tool integrated into QtCreator so that real TDD is possible. If you have tried it you will not write code without tests anymore. So no only generating a new class via the QtCreator templates but also a corresponding UnitTest and running it automatically after compile would be a dream.
This a more general question: how can QGraphicsSceneEvents be simulated in unit testing? QTest has support for QWidget events (like QTest::keyEvent) but not for QGraphicsWidgets.
@Alex
Just create the event and send it to the scene with QApplication::sendEvent().
@Yoann
Since events like QGraphicsSceneMouseEvent have no public constructor or property set methods I thought there might be established way to create and send them.
I agree 100% with Jens Stockhausen. TDD helpers in QtCreator are a must.
Yes, TDD in QtCreator would be really nice. Perhaps, the Test tool could be part of the qmake project file and be run automatically after building? so it would not opnly be integrated in QtCreator, but in all qmake build process...
Second the integration of some test-driven development features into QtCreator. If you compare use of QTestLib with QtCreator to, e.g., the JUnit tools available in Eclipse...
I would really like to see something comparable in QtCreator :-).