...

テスト自動化を再考しよう

by user

on
Category: Documents
19

views

Report

Comments

Transcript

テスト自動化を再考しよう
コべリティプライベートセミナー
テスト自動化を再考しよう
~ソフトウェア・サプライチェーン統制のことはじめ~
主催:コベリティ日本支社
共催:株式会社東陽テクニカ
Introduction to Coverity
September, 2013
Coverity について
Company Facts
Product Facts
• 2003年に Stanford University • C, C++ の静的解析からスタート
Research Laboratory 内で設立
• 現在では Java と C#をサポート
• 従業員 300 人 – 30% 以上が
• 品質、セキュリティ、テスト効率
R&D に所属
• 1ダースを超える特許
• San Francisco, Boston, New
化に関わる製品群
York, Seattle, Calgary,
London, Paris, 大阪, 東京,
Bangalore, Beijing
3
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
Customer Facts
• 1,100 を超える顧客
• 500 のオープン・ソースプ
ロジェクトを解析
• 100,000 ユーザ
• 50 億行のソースコードが
コベリティで解析されてい
る
コベリティのミッション
早期にバグ・脆弱性の修正を行い、後工程での手戻りを減らす
設計
開発
5倍のコスト
4
QA
10倍のコスト
製品リリース
& 管理
30倍のコスト
コベリティのミッション
早期にバグ・脆弱性の修正を行い、後工程での手戻りを減らす
早い段階で不具合を除去
設計
開発
5倍のコスト
5
QA
10倍のコスト
製品リリース
& 管理
30倍のコスト
あらゆる分野で適用
(C/C++, Java, C# をサポート)
Industrial Automation • Automotive • Gaming
Over 1,200 High Integrity Brands
Coverity Development Testing Platform
解析 | 修正 | 統制
解析パッケージ
SDLC 統合
Policy Manager
サードパーティ
メトリクス
Dynamic
Analysis
IDE
Coverity Connect
Architecture
Analysis
解析結果統合
コード
カバレッジ
Quality
Advisor
Security
Advisor
Test
Advisor
FindBugs™ |
FxCop
テスト
実行
ビルド/
継続的統合
バグ
トラッキング
SCM
解析結果統合
ツールキット
Coverity SAVE™
Static Analysis Verification Engine
商用コード | オープンソースコード
8
ALM 連携
HP | IBM
Improving Software Quality
Through
Test Automation
(Japanese version)
Andreas Kuehlmann
Senior Vice President of Research & Development,
Coverity
September, 2013
Coverity 社内の
テスト自動化プロセス
Coverity’s Internal Test Automation Process
10
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
コベリティのリリースプロセス
(Our Release Process)
一般的なリリースプロセス:
• 6 ヶ月のリリースサイクル
• 3 ヶ月の次期リリース計画
• リリース直前の6 週間の “ハードニング”
サイクル
• 2 週間の “フィーチャーフリーズ”
• 2 週間の “インテグレーションフリーズ”
• 2 週間の “リリースフリーズ” と GA のための
アップロード
• リリースのコードネームはカリフォルニ
ア州の都市名
リリースを実行するプロセス:
• アジャイルプロセス
• 部門横断的なスクラムチーム
• 2 週間のスプリント
• メールまたは対面での日次スタン
ド・アップ
• Jira と Pivotal を介した進捗管理
• Bugzilla によるバグ管理
• 週1回のステータスミーティング
• Alameda, Berkeley, Davis, Eureka, Fresno, …
1つのリリースの詳細
11
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
• リリースハードニングでは、週に3回
2年前の状況
(Where We Were Two Years Ago)
コベリティの製品構造概要:
2年前のテストアプローチ:
•
•
•
12
フロントエンドと解析のコンポーネントは自動化されたテストでテストされていた
ここでは、この最後の
Coverity Connect はほとんどが手動でテスト
2つのエリアに
End-to-End のテストは手動で行われていた
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
フォーカスします
2年前の状況
(Where We Were Two Years Ago)
• QA プロセスは東ヨーロッパでアウトソース
し実施していた
• 伝統的な QA スキル、開発スキルは
わずかかもしくは皆無
• 10時間の時差
• 言語的な壁
• 6 週間のハードニングサイクルは “ロシアン・ルーレット”のようなものだった
• “フィーチャー実装完” と “フィーチャーテスト” の時間的解離
• 開発者は品質に対して、即座の直接的な責任を感じていなかった
• 何に出くわすかわからない – “簡単なバグ” なのか “致命的バグ” なのか
• とるに足らないバグに QA サイクルの多くが費やされていた
• 手動のプロセスでは、テストを 2-3 回しか回せない
• 製品品質による苦しみ
• よい品質でリリースするために、チームは多くのストレスを抱えていた
13
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
矯正への最初の試み
(A First Attempt to Remediate)
• QAと開発の間の境界を取り除く
• 組織的
• 時間的 (開発とテストを織り込んでいく)
• 2011 初頭に組織を再編
• 2/3 の QA リソースを開発組織に移管
• 目的を、テストの自動化を通して、
“開発しながらテストする” ように設定した
• 結果は期待はずれだった
• QA チームはプログラミングに関してトレーニングされておらず、自動テストを開発
するのが困難であった
• テストの自動化に関しては、実際ごくわずかしか進歩しなかった
• 時差と言語の壁が存続していた
14
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
さらなる抜本的な改革
More Drastic Changes
15
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
抜本的な改革 – 人
(More Drastic Changes – People)
• リソースを東ヨーロッパから
カナダ、カルガリーに移動
• 1 時間の時差
• サンフランシスコから 2.5 時間のフライト
• 言語の壁がない
• エンジニアのインタビュープロセスに的を絞り
2011 年の夏に移行を開始
• 移行は12ヶ月以上かかった
• 多くは予算に影響を与えなかった
• スキルセットの変更
• テスト自動化に焦点をあてたプログラミング
スキル
• テストの自動化に対する高いモチベーション
16
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
抜本的な改革 – プロセス
(More Drastic Changes – Process)
• 可能なかぎり多くのテストの自動化に集中する。とりわけ、Coverity
Connect (CC) と End-to-End (E2E)
• 自動化されたテストにより2つの効果が得られる:
• フィーチャーに期待する挙動を成文化:
• テストと実装の間の “ネゴシエーション”
• テストがパスすれば、フィーチャーは “完了” と宣言できる
• 機能が完成したあとのリグレッションを検知できる
• 次のフィーチャーセットの作業をしている間の
意図しない機能の変更
• 将来のフィーチャー開発のための “ガードレール”
• 全てのテストがコードに密に連携して開発できるわけではない
• テストのためのよいアーキテクチャが要求される
17
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
Coverity Connect の自動テストの例
(Example of Automated Test in CC)
18
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
テスト自動化の進捗
(Progress in Test Automation)
• 2011年秋〜2013年春までの Coverity Connect と End-to-End のテスト自
動化の結果
19
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
テクノロジー
(Technology)
• 短いテストのほとんどはビルドプロセスの一部として実行される
• 自動化テストのスケジュールとレポートのため、システムを拡張
• すべてのプラットフォームのためのテストを
自動化するため、サーバに大きな投資
• システムの自動割当
20
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
テクノロジー
(Technology)
• “Product on Product” – 自分の製品を自ら試す
• “Coverity-クリーン” がリリース基準
21
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
テクノロジー
新しい製品の誕生
Technology – A New Product is Born
22
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
我々のテスト開発にフォーカス
(Focusing Our Test Development)
• ユニットテストへの注力とその進捗を計測する
良い方法を持ちあわせていなかった
• コードカバレッジはテスト工数に関しては良い指標ではない
• 新機能のコードは、全体のカバレッジで把握しにくい
• “開発しながらテストする”ことを牽引する計測可能な
基準の欠如
• ツールが必要:
• 以下のコードに着目した自動テスト開発をガイドする
• 新規コード
• リスクの高い部分を特に識別
• 関連のないコードを除外
• テストが不十分なコードを開発者に自動的に通知し、その対処を促すワークフロー
• アジャイルな受入れプロセスの一部として“テスト十分性”の施行を可能にする、管理
上の可視性
23
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
コードカバレッジに付随するチャンレジ
テストされたコード
(%)
(The Challenge with Code Coverage)
テスト工数の増加
に対し効果は減少
テスト作成の工数
24
テストできないコードも存
在
- 到達できないステートメ
ント
- デッドコード
-テストを行う価値がない
...
コード
- 重要でないコード
- デバッグコード、既存
コード
- 決まりきった例外処理
- …
Coverity コード (FE + Analysis)への試み
(Experiment on Coverity Code (FE + Analysis))
“チェンジセット”にフォーカスしたテストポリシーを評価する単純な試み
• フロントエンドと解析コード数:1,372,376 行
• 1,149,036 行がテストでカバー (83.7% カバレッジ), 223,340 行が未テスト
• 直前の変更にフォーカスすると、 145 ファイル内の 851 行をカバーする必要があ
る
Untested LOC
250,000
200,000
2500
223,340
1979
2000
1743
150,000
1500
1000
100,000
404
50,000
-
Untested LOC
Untested LOC (%)
# Incomplete Tested Files
9,636
Total
223,340
100.0%
1979
Since 5.3
9,636
2.0%
1743
7,934
Since 5.4
7,934
1.6%
404
145
500
851
Since 5.4.1
851
0.2%
145
0
# Incomplete Tested Files
Focus testing on latest changes
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
# Incomplete Tested Files
明らかに対処しやすい:
•
•
25
Untested LOC
未テストコードの 0.2%
未テストファイルの 7%
Test Advisor – 製品コンポーネント
テスト アドバイス
不十分なテストのリスクを見極める
アクション可能な作業項目
テストポリシー評価
• クリティカルコード解析
• チェンジインパクト解析
• テスト実行解析
テストモニタリン
グ
26
コードオーナと
変更履歴
静的コード解析
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
カスタマイ
ズ
テスト
ポリシー
Test Advisor への入力成分
テスト アドバイス
(Ingredient to Test Advisor)
不十分なテストのリスクを見極める
アクション可能な作業項目
テストポリシー評価
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
27
Gc_rc gc_pbkdf2_sha1 (const char *P, size_t Plen,
const char *S, size_t Slen,
unsigned int c,
char *DK, size_t dkLen)
{
char U[20] T[20];
unsigned int hlen = 20, u, l, r, i, k;
int rc; char *tmp; size_t tmplen = Slen + 4;
if (c == 0)
return GC_PKCS5_INVALID_ITERATION_COUNT;
r = dkLen - (l - 1) * hLen;
memcpy (tmp, S, Slen);
for (i = 1; i <= l; i++) {
memset (T, 0, hLen);
for (u = 1; u <= c; u++) {
if (u == 1) {
tmp[Slen + 0] = (i & 0xff000000) >> 24;
tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
tmp[Slen + 3] = (i & 0x000000ff) >> 0;
rc = gc_hmac_sha1 (P, Plen, tmp, tmplen, U);
}
else rc = gc_hmac_sha1 (P, Plen, U, hLen, U);
if (rc != GC_OK) {
free (tmp);
return rc;
}
for (k = 0; k < hLen; k++) T[k] ^= U[k];
#ifdef DEBUG
printf("Value: %d¥n", u);
#endif
}
memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen);
}
free (tmp);
return GC_OK;
}
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
テストモニタ
リング
コードオーナ
と
変更履歴
静的コード解
析
カスタ
マイズ
テスト
ポリ
シー
入力成分1:テスト実行からの入力
テスト アドバイス
(Input from Test Execution)
不十分なテストのリスクを見極める
アクション可能な作業項目
テストポリシー評価
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
28
Gc_rc gc_pbkdf2_sha1 (const char *P, size_t Plen,
const char *S, size_t Slen,
unsigned int c,
char *DK, size_t dkLen)
{
char U[20] T[20];
unsigned int hlen = 20, u, l, r, i, k;
int rc; char *tmp; size_t tmplen = Slen + 4;
if (c == 0)
return GC_PKCS5_INVALID_ITERATION_COUNT;
r = dkLen - (l - 1) * hLen;
memcpy (tmp, S, Slen);
for (i = 1; i <= l; i++) {
memset (T, 0, hLen);
for (u = 1; u <= c; u++) {
if (u == 1) {
tmp[Slen + 0] = (i & 0xff000000) >> 24;
tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
tmp[Slen + 3] = (i & 0x000000ff) >> 0;
rc = gc_hmac_sha1 (P, Plen, tmp, tmplen, U);
}
else rc = gc_hmac_sha1 (P, Plen, U, hLen, U);
if (rc != GC_OK) {
free (tmp);
return rc;
}
for (k = 0; k < hLen; k++) T[k] ^= U[k];
#ifdef DEBUG
printf("Value: %d¥n", u);
#endif
}
memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen);
}
テストモニタ
リング
コードオーナ
と
変更履歴
静的コード解
析
カスタ
マイズ
テスト
ポリ
シー
テスト実行中のコードインストゥルメント
(e.g. coverage tools) を通して
データを獲得
このコードは以下でテストされてい
る:
• Test_name1.c
• Test_name2.c
• …
このコードはテストされていない
free (tmp);
return GC_OK;
}
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
入力成分2: SCMからの入力
テスト アドバイス
不十分なテストのリスクを見極める
(Input from Source Code Repository (SCM))
アクション可能な作業項目
テストポリシー評価
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
29
Gc_rc gc_pbkdf2_sha1 (const char *P, size_t Plen,
const char *S, size_t Slen,
unsigned int c,
char *DK, size_t dkLen)
{
char U[20] T[20];
unsigned int hlen = 20, u, l, r, i, k;
int rc; char *tmp; size_t tmplen = Slen + 4;
if (c == 0)
return GC_PKCS5_INVALID_ITERATION_COUNT;
r = dkLen - (l - 1) * hLen;
memcpy (tmp, S, Slen);
for (i = 1; i <= l; i++) {
memset (T, 0, hLen);
for (u = 1; u <= c; u++) {
if (u == 1) {
tmp[Slen + 0] = (i & 0xff000000) >> 24;
tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
tmp[Slen + 3] = (i & 0x000000ff) >> 0;
rc = gc_hmac_sha1 (P, Plen, tmp, tmplen, U);
}
else rc = gc_hmac_sha1 (P, Plen, U, hLen, U);
if (rc != GC_OK) {
free (tmp);
return rc;
}
for (k = 0; k < hLen; k++) T[k] ^= U[k];
#ifdef DEBUG
printf("Value: %d¥n", u);
#endif
}
memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen);
}
テストモニタ
リング
コードオーナ
と
変更履歴
静的コード解
析
ソースコードレポジトリから
獲得したデータ
このコードは Albert Miller
によって 1987/12/14 に書か
れた
このコードは Peter Pan に
よって 2-9-2012/2/9 に書か
れた
このコーdは Dave Fastcode
によって 2012/3/18 に変更
された
free (tmp);
return GC_OK;
}
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
カスタ
マイズ
テスト
ポリ
シー
入力成分3: 静的解析からの入力
テスト アドバイス
(Static Analysis Intelligence)
1 int gc_hmac_sha1 (const char *P, size_t Plen,
2
1 Gc_rc gc_pbkdf2_sha1 (const char *P, size_t Plen,
3
2
const char *S, size_t Slen,
4
3
unsigned int c,
5
4
char *DK, size_t dkLen)
6
5 {
7
6
char U[20] T[20];
8
7
unsigned int hlen = 20, u, l, r, i, k;
9
8
int rc; char *tmp; size_t tmplen = Slen + 4;
10
9
11
10
if (c == 0)
12
11
return GC_PKCS5_INVALID_ITERATION_COUNT;
13
12
r = dkLen - (l - 1) * hLen;
14
13
15
14
memcpy (tmp, S, Slen);
16
15
for (i = 1; i <= l; i++) {
17
16
memset (T, 0, hLen);
18
17
for (u = 1; u <= c; u++) {
19
18
if (u == 1) {
20
19
tmp[Slen + 0] = (i & 0xff000000) >> 24;
21
20
tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
22
21
tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
23
22
tmp[Slen + 3] = (i & 0x000000ff) >> 0;
24
23
rc = gc_hmac_sha1 (P, Plen, tmp, tmplen, U);
25
24
}
26
25
else rc = gc_hmac_sha1 (P, Plen, U, hLen, U);
27
26
28
27
if (rc != GC_OK) {
29
28
free (tmp);
30
29
return rc;
31
30
}
32
31
for (k = 0; k < hLen; k++) T[k] ^= U[k];
33
32 #ifdef DEBUG
34
33
printf("Value: %d¥n", u);
35
34 #endif
35
}
36
memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen);
37
}
38
39
free (tmp);
40
return GC_OK;
41 }
30
不十分なテストのリスクを見極める
アクション可能な作業項目
テストポリシー評価
テストモニタ
リング
コードオーナ
と
変更履歴
静的コード解
析
カスタ
マイズ
テスト
ポリ
シー
コードのシンタックスとセマンティックス
根拠を深く理解する
強力なプロシージャ間静的解析
テストされる入力パラメー
タのチェックを識別
システムの他の部分の変更
の影響を受けるテストすべ
きコードの識別
テスト不要の
デバッグコードを識別
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
入力成分4: 強力なテストポリシー仕様
テスト アドバイス
(Powerful Specification for Test Policy)
不十分なテストのリスクを見極める
アクション可能な作業項目
テストポリシー評価
1 // Policy that requires 100% of code to be covered at the
2 // file granularity if it has changed since 2012-01-01,
3 // but ignores code that has only whitespace change
4 {
5
type: "Coverity test policy definition",
6
format_version: 1,
7
recent_date_cutoff: "2012-01-01",
8
old_date_cutoff: "2010-12-01",
9
10
rules: [
11
{
12
violation_name: "RECENT_CODE_NON_WS_CHG",
13
aggregation_granularity: "file",
14
minimum_line_coverage_pct: 100,
15
16
// Only look at recently changed lines.
17
line_filters: [
18
{
19
min_modified_date: "2012-01-01",
20
},
21 Policy that
], requires that all ways a function can terminate
//
//
22 normally be covered by tests.
// Only look at lines in functions whose syntactic
{23
24 type: "Coverity
// structure
changed.
test recently
policy definition",
25 format_version:
function_filters:
[
1,
26
{
27 rules: [
min_ast_date: "2012-01-01",
28
},
{
29
],
violation_name:
"cover-all-returns",
30
aggregation_granularity:
},
"function",
31
],
minimum_line_coverage_pct: 100,
// Tests must exercise all
// lines that
32
}, line_filters: [
{
contains_astnode: {
// contain an AST node that
is_function_end_statement: true, // is the last stemt before
// the function terminates
},
},
],
},
],
}
テストモニタ
リング
コードオーナ
と
変更履歴
カスタ
マイズ
テスト
静的コード解
析
ポリ
シー
製品コンポーネントやチームに合った
詳細度でテストポリシーを指定
• 30 以上のきめ細やかな基準を
テスト開発にフォーカスするために用意
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
31
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
新規コードは 100% テストす
ることを指定したポリシー
すべての関数の戻り値がテスト
されることを要求したポリシー
結果 – テスト違反
(The Result - Testing Violations)
テスト違反と
不具合の
統一ビュー
違反の
明確な記述
コード中のど
こで違反が発生
しているかを識
別
今後派生する
テストの出発点
32
Confidential : For Coverity and Partner use onl y. Copyright Coverity, Inc., 2013
違反を自動的
に
オーナに割当
て
社内での経験 – ケーススタディ
(In-House Experience – A Case Study)
• 十分テストされている製品のコンポーネントに Test Advisor を適用
• 1テストエンジニアが1週間のうち4時間、テスト違反の箇所にテストを追
加した
• テストポリシー: テスト可能なコードは 100% テストする (除外: デバッグ
コード, 実行されないコード, その他)
• 1人週間換算で29件のテストを追
加
• 製品から19件のバグを発見 – いく
つかは重大なもの
• 例: Keil コンパイラの正しい
機能を阻害するバグ
33
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
結果
(Results)
• テストの自動化に顕著な進展がみられた
• E2E テストの 97% が自動化された
• Coverity Connect の 25% のテストが自動化された– 次の春までに 80% 以上の自
動化を目指す
• 顧客が発見した不具合に計測可能なレベルの減少がみられた
34
詳細は http://www.coverity.com にて
• “テスト自動化”で検索ください
Confidential: For Coverity and Partner use only. Copyright Coverity, Inc., 2013
Fly UP