スポンサードリンク
こんにちは、ももやまです。
今回はソフトウェア分野の「テスト」について基本情報を出る部分を中心にまとめていきたいと思います。
目次
スポンサードリンク
1.テストとは
システム開発では、決められた要件に沿ってプログラムを記述していきます。
しかし、プログラムの記述は機械ではなく人間が行うものなので、プログラムのミス(バグ)を防ぐことは限りなく不可能に近いです。
ただ、ミスを防げないからといって「バグだらけのシステムをそのまま納品する」わけにはいきません。そんな怖いシステム誰も使いたくないですね。
そこで、システム開発では「ミスを減らす」のではなく、ミスを発見して、つぶすことでプログラムのバグを防いでいきます。
この「ミスを発見して、つぶす」こと(デバッグ)をテストで行います。
次の章以降では、テストの種類、様々なテストの方法について説明します。
スポンサードリンク
2.テストの流れ
テストは、
- まずは小規模(各モジュールごと)でテスト [単体テスト]
- 問題がなければ規模を大きくしてテスト [結合テスト]
- つぎに、システム全体を稼働させてテスト [システムテスト]
- 最後に利用者視点でシステムが問題なく動くかテスト [運用テスト]
という4ステップで行われます。
(下流工程から上流工程に向かってテストをすると思ってください)
4ステップそれぞれのテストが設計段階のどこにあたるかはV字モデル(下の図)を見るとわかりやすいかと思います。
スポンサードリンク
3.単体テストの2つのテスト技法
まずは、単体テストでのテスト技法を紹介しましょう。
単体テストでは、モジュールが思った通りの(仕様通り)の動きをするのかをテストします。
ただし、やみくもに入力(テストデータ)を決めてもあまりテストの効果はありません。
そこで、「ある一定の規則*1」に従ってテストする入力の種類を決定します。
よく行われるテストの方法として、
- ブラックボックステスト
- ホワイトボックステスト
があります。
(1) ブラックボックステスト
ブラックボックステストは、モジュール(プログラム)の内部をブラックボックスとして(内部を意識せず外部に注目して)テストする手法です。(利用者視点で行われるテストです。)
与えられた入力(テストデータ)に対して、正しく出力が得られるかをチェックします。
ブラックボックステストでは、主に「同値分割」、「境界値分析(限界値分析)」と呼ばれる方法でテストをする入力の種類(テストケース)を作成します。
同値分割
同値分割とは、データをある一定の範囲ごとにグループ化し、グループの中で代表的な値を1つ選ぶ方法です。
例えば、月(1~12)を入力するモジュールを考えましょう。この場合グループは、
- 有効値のグループ(1以上12以下が入力された場合)
- 有効値を超えた値を入力して無効になるグループ(12を超えた値が入力された場合)
- 有効値未満の値を入力して無効になるグループ(1未満の値が入力された場合)
の3つのグループに分けることができます。
この場合、
- 有効値のグループの代表例:8
- 有効値超過のグループの代表例: 17
- 有効値未満のグループの代表例: -5
のように代表的な値を取ることで同値分割が行えます。
もう少し難しい例を考えてみましょう。
例えば、100点満点のテストの成績を入力し、ある一定の成績ごと(0~59点、60~79点、80~100点)にランク分けするようなモジュールを考えましょう。この場合、グループは、
- 合格Aのグループ(80点以上100点以下の場合)
- 合格Bのグループ(60点以上79点以下の場合)
- 不合格のグループ(0点以上59点以下の場合)
- 有効値超過のため無効となるグループ(101点以上の場合)
- 有効値未満のため無効となるグループ(-1点以下の場合)
の5つに分けることができます。
この場合、
- 合格Aのグループの代表例: 85
- 合格Bのグループの代表例: 70
- 不合格のグループの代表例: 50
- 有効値超過のグループの代表例: 130
- 有効値未満のグループの代表例: -20
のように代表的な値を取ることで同値分割が行えます。
境界値分析(限界値分析)
境界値分析とは、データをある一定の範囲ごとにグループ化したときのグループの境目付近(境目+1 or 境目-1が多い)を重点的にチェックします。
先ほど同じ月(1~12)を入力するモジュールを例に考えましょう。この場合グループは、
- 有効値のグループ(1以上12以下が入力された場合)
- 有効値を超えた値を入力して無効になるグループ(12を超えた値が入力された場合)
- 有効値未満の値を入力して無効になるグループ(1未満の値が入力された場合)
の3つのグループに分けることができます。
この場合、境目は
- 有効値未満と有効値の部分 (0月と1月)
- 有効値と有効値超過の部分 (12月と13月)
にあるため、テストケースを
- 有効値未満と有効値の境目:0, 1
- 有効値と有効値超過の境目:12, 13
とすることで境界値分析(限界値分析)が行えます。
もう少し難しい例として、100点満点のテストの成績を入力し、ある一定の成績ごと(0~59点、60~79点、80~100点)にランク分けするようなモジュールを考えましょう。(こちらも先ほどと同じです)
グループは、
- 合格Aのグループ(80点以上100点以下の場合)
- 合格Bのグループ(60点以上79点以下の場合)
- 不合格のグループ(0点以上59点以下の場合)
- 有効値超過のため無効となるグループ(101点以上の場合)
- 有効値未満のため無効となるグループ(-1点以下の場合)
の5つに分けることができるます。
このとき境目部分は、
- 有効値未満と不合格の境目:0, 1
- 不合格と合格Bの境目:59, 60
- 合格Bと合格Aの境目:79, 80
- 合格Aと有効値超過の境目:100, 101
となるのでこの8つの値をテストケースとすれば境界値分析(限界値分析)が行えます。
(2) ホワイトボックステスト
ホワイトボックステストは、モジュール(プログラム)の内部に注目して(つまり、プログラムの中身を見て)テストを行います。
具体的には、プログラムの条件分岐(if文での分岐)に着目して、プログラムが正しく追跡(分岐するか)するかを調べます。
ホワイトボックステストでは、何を網羅する部分によって以下の4つの網羅方法があります。
では、これら4つの網羅方法がどのようなものなのかを以下のプログラムを例に説明していきましょう。
def ex1(A, B):
if A and B:
print("処理")
今回は、基本情報や応用情報の試験でも使われる「コード網羅率」におけるそれぞれの網羅方法を説明しています*2。
命令網羅 (C0)
命令網羅では、プログラム中にあるすべての命令を最低1回実行するようなテストケースを考えます。
上のフローチャートで表されるプログラムの例の場合、A and B
が真になるとき、つまりA, Bがともに真になるときのテストケースだけを考えればOKです。
A | B | 命令 | |
---|---|---|---|
1 | 真 | 真 | される |
もう1つ別の例を出してみましょう。
先程とは逆に、A and B
が偽のときだけ命令が実行されるようなプログラムを考えてみましょう。
この場合、A and B
が偽になるパターン、つまり
A = 真, B = 偽 A = 偽, B = 真 A = 偽, B = 偽
の3つのうちのどれか1つだけをテストケースとすれば命令網羅を満たします*3。
分岐網羅・判定条件網羅 (C1)
命令網羅では、プログラム中にあるすべての分岐を最低1回は通るテストケースを考えます。
例えば、下のフローチャートで表されるプログラムの場合、
A and B
が真のときに通る分岐A and B
が偽のときに通る分岐
の2つが確かめられていればOKです。
そのため、下の2つの入力をテストケースとすれば分岐網羅を満たすことができます。
A | B | A and B | 命令 | |
---|---|---|---|---|
1 | 真 | 真 | 真 | される |
2 | 真 | 偽 | 偽 |
なお、No.2のテストは、A and B
が偽になればいいので、
A = 偽, B = 真 A = 偽, B = 偽
でもOKです。
なお、分岐網羅はプログラム中のすべての分岐を試すため、分岐網羅(C1)を満たすテストケースであれば必ず命令網羅(C0)も満たします。
(すべての分岐を試せば「実行されない命令」は絶対にありませんよね。)
条件網羅 (C2)
条件網羅は、コード内の個々の条件について、すべての真偽が少なくとも1回は出現するようなテストケースを考えます。
例えば、下のフローチャートで表されるプログラムの場合、
A
が真になるときA
が偽になるときB
が真になるときB
が偽になるとき
の4つが確かめられていればOKです。
そのため、下の2つの入力をテストケースとすれば条件網羅を満たすことができます。
A | B | A and B | 命令 | |
---|---|---|---|---|
1 | 真 | 偽 | 偽 | |
2 | 偽 | 真 | 偽 |
なお、A, Bの真偽が少なくとも1回は出現すればいいので、テストケースは
A | B | A and B | 命令 | |
---|---|---|---|---|
1 | 真 | 真 | 真 | される |
2 | 偽 | 偽 | 偽 |
でもOKです。
条件網羅は個々の条件の真, 偽が1回でも出てくることに注目するため、
- すべての分岐をチェックすることができない
(分岐網羅(C1)を満たさない) - すべての命令が実行されないことがある
(命令網羅(C0)を満たさない)
ことがあります*4。
複数条件網羅 [複合条件網羅] (MCC)
複数条件網羅は、コード内の判定文におけるすべての条件で、とり得る真偽のすべてのパターンを(最低1回は)網羅するようなテストケースを考えます。
例えば、上のフローチャートで表されるプログラムの場合、下のように \( 2^{2} = 4 \) 通りの入力をテストケースとすることで複数条件網羅を満たすことができます。
A | B | |
---|---|---|
1 | 真 | 真 |
2 | 真 | 偽 |
3 | 偽 | 真 |
4 | 偽 | 偽 |
あれ、条件網羅(C2)の定義おかしくない?
参考書によっては条件網羅(C2)を「個々の条件について、全ての可能な結果を最低1回とるように実行するようなテストケース」と書かれている場合があります。(先程説明した複数条件網羅(MCC)に相当する条件です)
これは、基本情報や応用情報で使われる網羅方法(コード網羅率による網羅方法)と参考書による網羅方法(論理網羅と呼ばれます)が異なるために発生しています。
この記事では、基本情報や応用情報の対策をメインとするため、条件網羅は「すべての真偽が少なくとも1回は出現するようなテストケース」と記述しています。(後ろの練習問題でもこの定義を使います。)
4.命令網羅・分岐網羅・条件網羅・複数条件網羅を練習してみよう
ホワイトボックステストは少し難しいので、少し難しいプログラムの場合で理解できているかを確認しましょう。
問題
以下の関数 ex2
において、
- 命令網羅 (C0)
- 分岐網羅 (C1)
- 条件網羅 (C2)
- 複数条件網羅(複合条件網羅) (MCC)
を満たすテストデータの例を示しなさい。ただし、テストデータの個数が最小個数になるようにすること。
def ex2(x, y, z):
if x == 3 and y <= 5:
print("処理1")
else:
print("処理2")
if z > 0:
print("処理3")
※網羅を満たすテストデータを答える場合は、下のようにフローチャートを書くことを強くおすすめします。
(慣れれば書かなくてもいいですが…)
解答例
命令網羅 (C0)
命令網羅ということは、命令1、命令2、命令3がすべて実行されるようなテストケースを考える必要があります。
そのような最小のテストケースの例には、以下のようなものがあります。
x | y | z | 実行される命令 | |
---|---|---|---|---|
1 | 3 | 4 | 1 | 命令1, 命令3 |
2 | 2 | 6 | 1 | 命令2, 命令3 |
分岐網羅 (C1)
分岐網羅ということは、すべての分岐(分岐1~4と名前を付けましょうか)がすべて実行されるようなテストケースを考える必要があります。
そのような最小のテストケースの例には、以下のようなものがあります。
x | y | z | 実行される分岐 | |
---|---|---|---|---|
1 | 3 | 4 | 1 | 分岐1, 分岐3 |
2 | 2 | 6 | -1 | 分岐2, 分岐4 |
条件網羅 (C2)
条件網羅ということは、個々の条件の真, 偽がすべて実行されるようなテストケースを考える必要があります。
そのような最小のテストケースの例には、以下のようなものがあります。
x | y | z | x == 3 | y <= 5 | z > 0 | |
---|---|---|---|---|---|---|
1 | 3 | 6 | 4 | 真 | 偽 | 真 |
2 | 1 | 1 | -4 | 偽 | 真 | 偽 |
複数条件網羅 (MCC)
複数条件網羅ということは、個々の条件の真, 偽のパターンがすべて試されるようなテストケースを考える必要があります。
そのような最小のテストケースは、下の例のように \( 2^{3} = 8 \) 通り試す必要があります。
x | y | z | x == 3 | y <= 5 | z > 0 | |
---|---|---|---|---|---|---|
1 | 3 | 3 | 4 | 真 | 真 | 真 |
2 | 3 | 3 | -4 | 真 | 真 | 偽 |
3 | 3 | 6 | 4 | 真 | 偽 | 真 |
4 | 3 | 6 | -4 | 真 | 偽 | 偽 |
5 | 2 | 3 | 4 | 偽 | 真 | 真 |
6 | 2 | 3 | -4 | 偽 | 真 | 偽 |
7 | 2 | 6 | 4 | 偽 | 偽 | 真 |
8 | 2 | 6 | -4 | 偽 | 偽 | 偽 |
(なお、基本情報のような情報処理試験以外の参考書では複数条件網羅のことを条件網羅(C2)としているものもあるので注意しましょう)
論理的に全パターン試せない場合は…?
例えば、下のようなプログラムを例に考えましょう
if c == 'X' or c == 'Y':
print("1")
else:
print("2")
if c == 'Z':
print("3")
例えば、この場合だと c == 'X'
, c == 'Y'
, c == 'Z'
が2つ以上同時に真になることはありませんね。
このように、論理的に絶対に満たさないようなケースは想定する必要がありません。
つまり、上のプログラムの場合、論理的に満たす可能性のある下の4つのテストケースを試せばよいことがわかります。
c | c == 'X' | c == 'Y' | c == 'Z' | |
---|---|---|---|---|
1 | X | 真 | 偽 | 偽 |
2 | Y | 偽 | 真 | 偽 |
3 | Z | 偽 | 偽 | 真 |
4 | O | 偽 | 偽 | 偽 |
5.様々なテスト支援ツール
(1) テスト支援ケースの種類
先程は1つの条件文に対してテストケースを考えてきました。
しかし実際のプログラムは条件文などが非常に複雑に絡み合っています。
そのため、テストの数は膨大になってしまい、我々人間だけでテストを行うには非常に時間がかかってしまいます。
そこで、テストを行う時間を短くするような支援ツールが導入されました。
支援ツールには大まかに分けると、
- 静的テスト支援ツール
(プログラムを実行せずにプログラムの検証を行う*5) - 動的テスト支援ツール
(プログラムを実行しながらプログラムの検証を行う) - 環境設定ツール
(テスト環境、テストケースを作成する)
の3種類があります。
この中でも動的テスト支援ツールについての出題が多いため、今回は動的テスト支援ツールに絞って説明をします。
(2) 動的テスト支援ツール
代表的な動的テスト支援ツールには、以下のようなものがあります。
インスペクタ
プログラムの実行の際に使われた変数や、構造体の中身を確認することができます。
トレーサ
プログラムの実行過程を追跡、可視化します。
「トレース」で追跡するという意味なので、追跡するツールと頭に入れておきましょう*6。
アサーションチェッカー
プログラムの正当性をチェックします。
具体的には、変数間の関係や条件のような「論理的に成立する条件」をある個所に入れ、実行の際に成立するかを確かめます。
テストカバレージ分析ツール
ホワイトボックステストでのテストの網羅率(カバレージと呼びます)がどれくらいなのかを定量的に測定します。
6.結合テスト(統合テスト)
単体テストをクリアすると、クリアしたモジュールをつなぎ合わせてテストを行う結合テスト(統合テスト)を行います。
結合テストには、モジュールの上位からテストするか下位からテストするかによって
- トップアップテスト(上位からテスト)
- ボトムアップテスト(下位からテスト)
の2種類があります。
(1) トップアップテスト
トップアップテストは、モジュールの上位側から順番にテストをしていく方法です。
しかし、結合テストを始める前にすべてのモジュールが出来てないこともあります。
このようにまだ完成していないモジュールがある場合、スタブと呼ばれる仮のモジュールを付けることによりテストを行います。
(2) ボトムアップテスト
ボトムアップテストは、モジュールの下位側から順番にテストをしていく方法です。
ボトムアップテストではまだ完成していないモジュールがある場合、ドライバと呼ばれる仮のモジュールを付けることによりテストを行います。
トップアップテスト:スタブ
ボトムアップテスト:ドライバ
7.信頼性成長モデル(バグ管理図)
「このプログラム(モジュール)にはバグがない」ことを証明することは非常に難しいです。
ですが、プログラムのバグを見つけ、修正して…、また見つけ…、を繰り返していくことでバグが十分に発見された、つまり「品質のよいシステムだ」というのを言うことができます。
この「品質のよいシステムだ」と判断するために使うものが下の信頼性成長モデル(ゴンベルツ曲線とも呼ばれます)です。
信頼性成長モデルでは、下の1~3の流れでバグが発見されることを表しています。
- 最初はバグが緩やかに発見される
- 途中から急激にバグが発見される
- 最終的にバグの発見は緩やかになり、頭打ちになる
累積バグ件数とテスト項目消化件数に対する図(バグ管理図)が下のようなグラフになってしまう(信頼性成長モデルに従わない)場合は、まだバグが残っている(十分な品質ではない)可能性が高いです。
8.練習問題
では、5問ほど基本情報の問題で練習しましょう。
練習1
ホワイトボックステストの説明として,適切なものはどれか。
[基本情報技術者平成23年特別 午前問49]ア:外部仕様に基づいてテストデータを作成する。
イ:同値分割の技法を使用してテストデータを作成する。
ウ:内部構造に基づいてテストデータを作成する。
エ:入力と出力の関係からテストデータを作成する。
練習2
表は、あるプログラムの入力データを、有効同値クラスと無効同値クラスに分けたものである。同値分割法によってテストケースを設計する場合、最小限のテストデータの組み合わせとして、適切なものはどれか。
同値クラス | データ |
---|---|
無効同値クラス | -2, -1, 0 |
有効同値クラス | 1, 2, 3, 4, 5 |
無効同値クラス | 6, 7, 8 |
ア:-2, 0, 1, 5, 6, 8
イ:0, 1, 5, 6
ウ:-1, 3, 6
エ:1, 5
練習3
整数 1~1,000 を有効とする入力値が、1~100 の場合は処理Aを、101~1,000 の場合は処理Bを実行する入力処理モジュールを、同値分割法と境界値分析によってテストする。次の条件でテストするとき、テストデータの最小個数は幾つか。
☆条件☆
- 有効同値クラスの1クラスにつき、一つの値をテストデータとする。ただし、 テストする値は境界値でないものとする。
- 有効同値クラス、無効同値クラスの全ての境界値をテストデータとする。
ア:5
イ:6
ウ:7
エ:8
練習4
流れ図で表される部分を命令網羅によってテストするとき、テストケースは少なくとも幾つ用意する必要があるか。
[基本情報技術者平成28年春期 午前問49]
ア:2
イ:3
ウ:4
エ:5
練習5
プログラムの流れ図で示される部分に関するテストデータを、判定条件網羅(分岐網羅)によって設定した。このテストデータを複数条件網羅による設定に変更したとき、加えるべきテストデータのうち、適切なものはどれか。ここで、()で囲んだ部分は、一組のテストデータを表すものとする。
- 判定条件網羅(分岐網羅)によるテストデータ
(A=4、B=1), (A=5、B=0)
ア:(A=3, B=0), (A=7, B=2)
イ:(A=3, B=2), (A=8, B=0)
ウ:(A=4, B=0), (A=8, B=0)
エ:(A=7, B=0), (A=8, B=2)
練習6
プログラム実行中の特定の時点で成立する変数間の関係や条件を記述した論理式を埋め込んで、そのプログラムの正当性を検証する手法はどれか。
ア:アサーションチェック
イ:コード追跡
ウ:スナップショットダンプ
エ:テストカバレッジ分析
練習7
ボトムアップテストの特徴として、適切なものはどれか。
[基本情報技術者平成27年秋期 午前問48]ア:開発の初期の段階では、並行作業が困難である。
イ:スタブが必要である。
ウ:テスト済みの上位モジュールが必要である。
エ:ドライバが必要である。
9.練習問題の答え
解答1
解答:ウ
[それぞれの選択肢]ア:外部仕様に基づいてテストデータを作成する。
→ ブラックボックスの説明。ホワイトボックスでは内部仕様に基づいてテストデータを作成する。
イ:同値分割の技法を使用してテストデータを作成する。
→ 同値分割はブラックボックステストの手法。
ウ:内部構造に基づいてテストデータを作成する。
→ 正解。
エ:入力と出力の関係からテストデータを作成する。
→ ブラックボックスでの手法。
解答2
解答:ウ
同値分割法は、それぞれの同値クラス(グループ)が取りうる値を最低1つ選んでテストを行う方法である。
そのため、無効同値クラス(有効値未満)、有効同値クラス、無効同値クラス(有効地超過)からそれぞれ値を1つ選んでいるウが答えとなる。
解答3
解答:エ
まず、入力値がどのクラスに分けられるのかを表で表してみよう。
同値クラス | データ範囲 |
---|---|
有効値未満 | 0以下 |
処理A | 1以上100以下 |
処理B | 101以上1,000以下 |
有効値超過 | 1,001以上 |
まず、「有効同値クラスの1クラスにつき、境界値以外の1つの値をテストデータとする。」ので、処理Aと処理Bで2つのテストデータが必要となる。
つぎに、「有効同値クラス、無効同値クラスの全ての境界値をテストデータとする。」とある。今回は、
- 有効値未満と処理Aの境界
- 処理Aと処理Bの境界
- 処理Bと有効値超過の境界
の3か所に境界がある。
1つの境界につき、2つのテストデータ(境界値ちょうどと1だけ外れた値)が必要になるので、合計2×3=6通りのテストケースが必要となる。
よって、合計2+6=8通りのテストケースが必要なので答えはエ。
解答4
解答:ア
命令網羅なので、x=1
, x=2
, y=1
,y=2
のすべての命令を網羅すればよい。
そのため、以下の2つの命令を使えば最小個数のテストケースとなる。
a | b | 命令 | |
---|---|---|---|
1 | 0 | 0 | x=1, y=1 |
2 | 1 | 1 | x=2, y=2 |
(もちろん (a,b) = (0,1), (1,0) の2個でもOK)
よって答えはア。
解答5
解答:エ
複数条件網羅で必要になるテストケースは、以下の4つである。
(1) A > 6 を満たし、B = 0 も満たす場合 (2) A > 6 を満たし、B = 0 を満たさない場合 (3) A > 6 を満たさず、B = 0 を満たす場合 (4) A > 6 を満たさず、B = 0 も満たさない場合
ここで、判定条件網羅により (A,B) = (4,1), (5,0) はすでに入っている。(A,B)=(4,1) のときは(4)の条件に、(A,B) = (5,0)のときは(3)の条件を満たしているため、残りの(1),(2)の条件を満たすテストケース、つまり
(1) A > 6 かつ B = 0 となるとき (2) A > 6 かつ B ≠ 0 となるとき
を選べばよい。
そんなケースになるのはエが答え。
解答6
解答:ウ
「アサーションチェッカー→プログラムの正当性を調査する。」も覚えておきましょう。
解答7
解答:エ
ア:開発の初期の段階では、並行作業が困難である。
→ モジュールを分割しているため、並行作業が可能である。
イ:スタブが必要である。
→ スタブが必要なのはトップダウンテスト。
ウ:テスト済みの上位モジュールが必要である。
→ 上位モジュールの代わりにドライバを使うことで上位モジュールなしにテストが行えます。
エ:ドライバが必要である。
→ 正解。
10.さいごに
今回は、ソフトウェア分野における「テスト」についての説明でした。
基本情報に頻出する以下の項目はぜひ頭に入れておきましょう。
- ブラックボックステストとホワイトボックステストの違い
- ブラックボックステストで出てくる同値分割と境界値分析
- ホワイトボックステストで出てくる各種網羅方法
- スタブとドライバの違い
- 様々なテスト支援ツール
- 信頼性成長モデルについて(バグ管理図)
ソフトウェアについての記事はここまでです!
Part10までお読みいただきありがとうございました!
*1:誰でも客観的に(テストする人の主観が入らないような)テストができる規則となっている必要がある。
*2:「コード網羅率」以外に実務でも使われる網羅(カバレッジ)の基準に「論理網羅」があります。「論理網羅」では、コード網羅の複数条件網羅(MCC)を条件網羅(C2)と呼ぶため、基本情報や応用情報の参考書を読んだ人は違和感あるかもしれません。
*3:満たす=網羅率100%になるという意味です。
*4:まさに条件網羅の1種類目のテストケースが該当しますね
*5:自動構文チェッカーなどが該当する
*6:プログラミング系の授業で「とりあえずこのプログラムの動きをトレースしてみよう」と言われることありませんでしたか。私は先生によく言われていました。
関連広告・スポンサードリンク