単体テスト設計のコツ

Similar documents
040402.ユニットテスト

変更の影響範囲を特定するための 「標準調査プロセス」の提案 2014年ソフトウェア品質管理研究会(30SQiP-A)

SuperH RISC engineファミリ用 C/C++コンパイラパッケージ V.7~V.9 ご使用上のお願い

目次 ペトリネットの概要 適用事例

SuperH RISC engine C/C++ コンパイラ Ver.7 不具合内容 - 過去のお知らせ SuperH RISC engine C/C++ コンパイラ Ver.7 台における不具合内容を以下に示します のチェックツールをルネサスエレクトロニクス株式会社のホームページ

プログラミング実習I

Using VectorCAST/C++ with Test Driven Development

スライド 1

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

CodeRecorderでカバレッジ

PowerPoint プレゼンテーション

目次 研究目的 背景システム開発について実験および評価結論

概要 プログラミング論 変数のスコープ, 記憶クラス. メモリ動的確保. 変数のスコープ 重要. おそらく簡単. 記憶クラス 自動変数 (auto) と静的変数 (static). スコープほどではないが重要.

メソッドのまとめ

Microsoft PowerPoint - 09.pptx

2015 TRON Symposium セッション 組込み機器のための機能安全対応 TRON Safe Kernel TRON Safe Kernel の紹介 2015/12/10 株式会社日立超 LSIシステムズ製品ソリューション設計部トロンフォーラム TRON Safe Kernel WG 幹事

Microsoft PowerPoint - ETEC-CLASS1資料 pptx

<4D F736F F F696E74202D20835C CC967B8EBF2E B8CDD8AB B83685D>

Cコンパイラパッケージお知らせ

相続支払い対策ポイント

150423HC相続資産圧縮対策のポイント

ハピタス のコピー.pages

Copyright 2008 All Rights Reserved 2

Microsoft Word - no02.doc

プログラミング実習I

Microsoft PowerPoint - 【最終提出版】 MATLAB_EXPO2014講演資料_ルネサス菅原.pptx

Javaの作成の前に

エンジニアリング・サービスから見たMBD導入の成功・失敗

トレーニングのプレゼンテーション

PowerPoint プレゼンテーション

スライド 1

Microsoft PowerPoint - CproNt02.ppt [互換モード]

(Microsoft PowerPoint - \201yF3-1\201z\215\305\217Ijasst2010\215u\211\211\216\221\227\277.ppt)

02: 変数と標準入出力

02: 変数と標準入出力

メディプロ1 Javaプログラミング補足資料.ppt

5-3- 応統合開発環境に関する知識 1 独立行政法人情報処理推進機構

Microsoft PowerPoint - ●SWIM_ _INET掲載用.pptx

智美塾 ゆもつよメソッドのアーキテクチャ

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

PowerPoint プレゼンテーション

スライド 1

Insert your Title here

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

Microsoft PowerPoint - OS07.pptx

初心者にもできるアメブロカスタマイズ新2016.pages

MMUなしプロセッサ用Linuxの共有ライブラリ機構

外部からの脅威に対し ファジング の導入を! ~ さらなる脆弱性発見のためのセキュリティテスト ~ 2017 年 5 月 10 日独立行政法人情報処理推進機構技術本部セキュリティセンター小林桂 1

- 2 Copyright (C) All Rights Reserved.

Copyright 2014 NTT DATA Corporation 2 INDEX 1. 一括請求 Assist とは 1-1. でんさいに係るサービスの関係性 1-2. 一括請求 Assist の必要性 1-3. 一括請求 Assist の特長 2. 機能紹介 2-1. 一括請求 Assist

PowerPoint プレゼンテーション

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

Prog1_10th

ブート領域、フラッシュ領域の分割方法 RL78ファミリ用Cコンパイラ CC-RL

PowerPoint プレゼンテーション

02: 変数と標準入出力

Microsoft PowerPoint - handout07.ppt [互換モード]

ソフトウェア FMEA を体系的に実施する 出発点としての MISRA-C 株式会社ヴィッツ森川聡久 株式会社ヴィッツ中野泰伸 名古屋市工業研究所小川清 1


本書は INpMac v2.20(intime 5.2 INplc 3 Windows7/8/8.1に対応 ) の内容を元に記載しています Microsoft Windows Visual Studio は 米国 Microsoft Corporation の米国及びその他の国における登録商標です

Copyright All Rights Reserved. -2 -!

Microsoft Word - matlab-coder-code-generation-quick-start-guide-japanese-r2016a

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

PowerPoint プレゼンテーション

Microsoft Word - Training10_プリプロセッサ.docx

トレーニングのプレゼンテーション

IPA:セキュアなインターネットサーバー構築に関する調査

関数の動作 / printhw(); 7 printf(" n"); printhw(); printf("############ n"); 4 printhw(); 5 関数の作り方 ( 関数名 ) 戻り値 ( 後述 ) void である. 関数名 (

<4D F736F F D F193B994AD955C D9E82DD835C EC091D492B28DB8816A2E646F63>

Microsoft PowerPoint - B3-3_差替版.ppt [互換モード]

PowerPoint プレゼンテーション

ハード・ソフト協調検証サービス

02: 変数と標準入出力

Microsoft Word - 最終版 バックせどりismマニュアル .docx

.NET テクノロジー概説 /WindowsAzure 入門 コード P-2 0:00~7:00 ( 休憩 時間含む ) 前提条件 Windows の操作経験 ( エクスプローラの操作 ファイルの操作 ) があること 最低開講人数 0 名.NET テクノロジー概説 /WindowsAzure 入門

目次 はじめに 4 概要 4 背景 4 対象 5 スケジュール 5 目標点 6 使用機材 6 第 1 章 C# 言語 7 C# 言語の歴史 7 基本構文 8 C 言語との違い 9 Java 言語との違い 10.Netフレームワーク 10 開発資料 10 第 2 章 Mono 11 Monoの歴史 1

第1回 プログラミング演習3 センサーアプリケーション

AquesTalk プログラミングガイド

2 概要 市場で不具合が発生にした時 修正箇所は正常に動作するようにしたけど将来のことを考えるとメンテナンス性を向上させたいと考えた リファクタリングを実施して改善しようと考えた レガシーコードなのでどこから手をつけて良いものかわからない メトリクスを使ってリファクタリング対象を自動抽出する仕組みを

Microsoft PowerPoint - 計算機言語 第7回.ppt

KDDI Smart Mobile Safety Manager Mac OS キッティングマニュアル 最終更新日 2019 年 4 月 25 日 Document ver1.1 (Web サイト ver.9.6.0)

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

5-3- 基統合開発環境に関する知識 1 独立行政法人情報処理推進機構

スライド 1

HIGIS 3/プレゼンテーション資料/J_GrayA.ppt

Source Insight

PPTVIEW

モデリングとは

スキル領域 職種 : ソフトウェアデベロップメント スキル領域と SWD 経済産業省, 独立行政法人情報処理推進機構

システムインテグレータのIPv6対応

JUnit 概要 2015/4/16 版今泉俊幸 2015 bbreak Systems 1

GEC-Java

arduino プログラミング課題集 ( Ver /06/01 ) arduino と各種ボードを組み合わせ 制御するためのプログラミングを学 ぼう! 1 入出力ポートの設定と利用方法 (1) 制御( コントロール ) する とは 外部装置( ペリフェラル ) が必要とする信号をマイ

スライド 1

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

PowerPoint プレゼンテーション

Microsoft Visual Studio 2010 Professional Data Sheet

Microsoft PowerPoint - 13th.ppt [互換モード]

Transcription:

ESEC2011 ブース内セッション 単体テスト設計のコツ 日本システム開発株式会社 http://www.nskint.co.jp Copyright 2011 日本システム開発株式会社 All Rights Reserved

目次 1. ユニットテストについて知っておかないといけないこと 1-1. 品質問題の原因とユニットテストの関係 1-2. ソースコードレビューとユニットテストの違い 2. 有効なユニットテストデータの与え方 [ 事例 ] 2-1. [ 事例 1] 有効な値が 10~20 の unsigned short 変数 2-2. [ 事例 2] 参照のみ行う領域の確認 2-3. [ 事例 3] メモリ破壊が起きるコピー処理 3. 危険コードに対するテストデータの与え方 [ 事例 ] 3-1. [ 事例 1] 欠陥となる可能性がある符号変換処理 3-2. [ 事例 2] オーバーフローに誘発されたゼロ割処理 4. ユニットテストまとめ 2

1. ユニットテストについて 知っておかないといけないこと 3

1-1 品質問題の原因とユニットテストの関係 不具合の原因の割合 約 6 割がソフトウェアの不具合 引用 : 2010 年版組込みソフトウェア産業実態調査報告書 - 事業責任者向け調査 - ( 経済産業省 ) 品質の悪い製品を作り出す原因の一部は ユニットテストにある ユニットテストは製品不具合の原因に直接的直接的または関与する または間接的間接的に 4

1-1 品質問題の原因とユニットテストの関係 製品欠陥に対して直接的に関与する場合 ユニットテスト欠陥の流出 ユニットテスト工程で検出すべき欠陥を 検出できなかった そのまま製品が出荷されたため欠陥が発生し 品質問題による損失を発生させた レビュー ユニットテスト 統合テスト 検出できなかった ユニットテスト工程以降でも欠陥を検出できず そのまま流出させてしまった 5

1-1 品質問題の原因とユニットテストの関係 製品欠陥に対して間接的に関与する場合 ユニットテスト以降のテストが不十分 ユニットテスト工程に不備があり その後のテスト工程で行うはずであった機能テストなどが十分に実施できなかった 必要なテストが不十分なまま出荷されたため欠陥が発生し 品質問題による損失を発生させた 予定 ユニットテスト統合テスト 実績 検出できなかった ここで検出 ユニットテスト欠陥の対応 統合テストが十分にできず 統合テストで検出すべき欠陥を流出させてしまった 直接の原因が統合テストであるため そもそもの原因であるユニットテストに改善の意識が向きにくい 6

1-2 ソースコードレビューとユニットテストの違い ユニットテストに対するよくある誤解 ソースコードレビューをしっかり行えば ユニットテストは実施しなくても問題ないのでは? ユニットテストは実施しなければならない ユニットテストとソースコードレビューの工程の目的は大きく異なるため ユニットテスト工程を省略することは不可能 ユニットテストを実施しないと 他の工程は本来の目的を果たすことができない 仮に現状ユニットテスト工程を省略していて問題が出ないとしても 今の開発体制が崩れたら問題が発生する可能性は大 7

1-2 ソースコードレビューとユニットテストの違い ソースコードレビューとユニットテストの比較 ユニットテストのコツとして ソースコードレビューとの違いを認識しておくことが重要 同じ 工程評価対象評価範囲インプット評価内容欠陥検出範囲品質保証 ソースコードレビュー ソースコード 関数詳細設計静的分析 仕様網羅性確認コーディング規約適用確認冗長性確認コメント確認タイミング欠陥確認 ( ロバスト性確認 ) 不可能 ユニットテスト 実行モジュール 関数詳細設計動的分析 仕様網羅性確認コードカバレッジ確認ロバスト性確認 可能 ( 動作させた範囲 ) ソースコードレビューとユニットテストは 評価範囲 と インプット は同じだが それ以外は異なる 8

1-2 ソースコードレビューとユニットテストの違い ソースコードレビュー以外では検出できない欠陥 Q. タイミングによる欠陥を検出できるか? : : void void func() func() {{ if if (1 (1 == == a) a) {{ b b = = a; a; }} return; return; }} : : a が 1 の時に b を a(1) にすることを期待しているが 割り込みが上がると期待しない結果になる ここで割り込み a = 3; ユニットテスト以降の工程でこの状況を確実に作り出すことはできない A. ソースコードレビューなら タイミングによる欠陥を検出できる 9

1-2 ソースコードレビューとユニットテストの違い ユニットテスト以外では検出できない欠陥 Q. コンパイル環境によって動作が異なる場合 必ず正しいソースコードレビューが行えるか? : : unsigned unsigned char char a a = = 255, 255, b b = = 255; 255; unsigned unsigned short short c; c; c c = = (unsigned (unsigned short)(a short)(a + + b); b); : : ある環境では 510 ある環境では 254 A. レビューアが全てのコンパイラの動作を把握することはほぼ不可能であるため 必ず正しく行えるとは限らない 実際に動作させるユニットテストで差分を検出する必要がある 10

1-2 ソースコードレビューとユニットテストの違い まとめ 1. 欠陥検出範囲はソースコードレビューの方が広いソースコードレビューの方が多くの欠陥を検出できる 2. ユニットテストは機械的に全ステップ評価する唯一の工程目視で行うソースコードレビューに対し ユニットテストは機械的にテストすることでヒューマンエラーを防ぐ ユニットテストの後工程では全ステップに対してテストを行わないため ユニットテストでステップに対する評価を完了しておく必要がある 3. ソースコードレビューは品質証明にならないソースコードレビューはレビューアがNGと判断した箇所だけに指摘が出るため 他に欠陥が10 件潜伏している可能性も 100 件潜伏している可能性もある ユニットテストは品質証明になる ユニットテストは与える INPUT に対するテスト結果を記録として残すため この INPUT を与えれば正常に動作する ということを証明できる (INPUT を網羅する必要あり ) ソースコードレビューとユニットテストは共に必要 ( それぞれで何を重視すればよいか? が重要となる ) 11

2. 有効なユニットテストデータの 与え方 [ 事例 ] 12

2 有効なユニットテストデータの与え方 [ 事例 ] 有効なユニットテストにするために重要なこと どのようなテストケースを作成するか どのようなテストデータを与えるか このようなユニットテストを OJT で行うことは難しい ( 現場に指導できる人材が少ない ) 有効なユニットテストを考えるための事例 [ 事例 1] 有効な値が 10~20 の unsigned short 変数 [ 事例 2] 参照のみ行う領域の確認 [ 事例 3] メモリ破壊が起きるコピー処理 13

2-1 [ 事例 1] 有効な値が 10~20 の unsigned short 変数 同値分割とは 同値分割 同値分割はテストデータを抽出する手法の一つ 起こりうるすべての事象を洗い出し 同じ事象を発生させる入力値の集合を作成 この入力値の集合を同値クラスと呼ぶ 同値分割では 同値クラスから代表値を選出し テストデータとする 14

2-1 [ 事例 1] 有効な値が 10~20 の unsigned short 変数 例 ) 有効な値が 10~20 の unsigned short 変数の場合 long func(unsigned short data) { if ((10 <= data) && (20 >= data)) { : } : } 10 20 を境界とした同値クラスに分割 分割した同値クラスから代表値を選出 同値クラスの代表値 同値クラス 同値クラス 同値クラス 0 9 10 15 20 21 50 Q.data の初期値に何の値を指定するか? A. 例えば 0 15 50 を指定したとする しかし 50 では欠陥が検出できない可能性がある 15

2-1 [ 事例 1] 有効な値が 10~20 の unsigned short 変数 例 ) 有効な値が 10~20 の unsigned short 変数の場合 検出できない欠陥と対策 50をテストデータとして指定 50 上位バイト 0000 0000 下位バイト 0011 0010 2 バイトの変数である 有効範囲は 10~20 の 1 バイト範囲である 下位バイトが有効値と同じビットの値の評価が正しくできない可能性がある ( 例えば 266 が有効値とみなされる欠陥 ) 266をテストデータとして指定 266 上位バイト 0000 0001 下位バイト 0000 1010 対策変数を2バイトで評価しているか検証できる値を使用する ( 例えば266) 上位バイトを評価に使用しているか確認できる 下位バイトが有効範囲内であれば 誤った判断をしていないか確認できる 16

2-2 [ 事例 2] 参照のみ行う領域の確認 例 ) 参照のみ行う領域を更新していないことを確認する場合 関数 func() は外部変数 flag を参照している ( 更新はしない ) 外部変数 flag 参照 flag が更新されていないことを確認 func() を呼び出す前と後で flag の値が同じであればよい flag に xx を設定 関数 func() func() 呼び出し flag が xx か? flag が xx なら 更新していない Q.flag の初期値に何の値を指定するか? A. 例えば 1 を指定したとする しかし 1 では欠陥が検出できない可能性がある 17

2-2 [ 事例 2] 参照のみ行う領域の確認 例 ) 参照のみ行う領域を更新していないことを確認する場合 検出できない欠陥と対策 関数 func() は外部変数 flagを参照している ( 更新はしない ) flagの初期値として 1 を指定 func() 呼び出し前 flag = 1 func() 呼び出し後 flag = 1? 外部変数 flag 参照 関数 func() 偶然初期値と同じ値に flag を更新している可能性がある 一般的によく使用する値 (1 や 0) では 意図しない所で偶然初期値と同じ値に書き換えられている可能性がある 対策マジックナンバー (0xaaなど) を指定する値を変えて複数回テストする 18

2-3 [ 事例 3] メモリ破壊が起きるコピー処理 例 ) 配列をコピーする場合 From To Size を指定してコピーを行う処理 (From To はメモリのどこでも指定できる ) From To 元データ コピー先 Size 元データ (From) がコピー先 (To) へ Size の値だけコピーできていればよい 多くの場合 サイズに着目したテストを実施している (0 配列の最大値を指定 ) しかし サイズだけに着目したテストでは 欠陥が検出できない可能性がある 19

2-3 [ 事例 3] メモリ破壊が起きるコピー処理 例 ) 配列をコピーする場合 検出できない欠陥 コピー元データの開始位置 (From) コピー先データの開始 (To) データサイズ (Size) の関係によって発生するメモリ破壊 メモリ破壊が起きるパターン 1 元データの後方とコピー先の領域が重なっている場合 元データ コピー先 先頭から順にコピーすると 後方のデータを使用する時にはコピー処理により上書きされてしまっている 2 元データの前方とコピー先の領域が重なっている場合 コピー先 元データ 末尾から順にコピーすると 前方のデータを使用する時にはコピー処理により上書きされてしまっている 20

2-3 [ 事例 3] メモリ破壊が起きるコピー処理 例 ) メモリ破壊が起こるコピー処理 対策 コピー処理がある場合の正しいテスト観点 From To Size この 3 つの組み合わせが必要 From 元データ To コピー先 Size 組み合わせを考えないとテストに抜けが発生する 21

3. 危険コードに対する テストデータの与え方 [ 事例 ] 22

3 危険コードに対するテストデータの与え方 [ 事例 ] 危険コードに対するテストデータ 危険コードは多くの値で正常に動作するが ある特異な値を与えた場合に欠陥となる危険コードを考慮しないとテストが漏れる 本章で紹介する事例 [ 事例 1] 欠陥となる可能性がある符号変換処理 [ 事例 2] オーバーフローに誘発されたゼロ割処理 23

3-1 [ 事例 1] 欠陥となる可能性がある符号変換処理 例 )signed 変数を unsigned 変数として扱いたい場合 long func(signed char arg) { : if (0 > arg) { arg = -arg; // 符号変換処理 } : } 符号変換処理としてよく実装されるが 欠陥が潜んでいる これまで複数のプロジェクトで同じ誤りがあった Q.arg に何の値を指定するか? A. 例えば 10-10 を指定したとする しかし 10-10 では欠陥が検出できない可能性がある 24

3-1 [ 事例 1] 欠陥となる可能性がある符号変換処理 例 )signed 変数を unsigned 変数として扱いたい場合 検出できない欠陥とポイント long func(signed char arg) { : if (0 > arg) { arg = -arg; // 符号変換処理 } : } この符号変換処理において 符号を変換できない値が 1 点だけ存在する arg に -128 を与えた場合のみ 符号変換処理を行っても符号が変換されないため unsigned 変数として扱うことができない ポイント argに-128が指定されないことを確認する -128が指定される場合 指定されても問題ないことを確認する 25

3-2 [ 事例 2] オーバーフローに誘発されたゼロ割処理 例 ) 演算後に除算している場合 long func(unsigned char arg1) { :: a = (b / (unsigned char)(arg1 + 5)); :: } arg1 を +5 しているため ゼロ割が発生しないと判断を誤りやすい arg1 = 0 long func() {{ :: }} Q.arg1 に何の値を指定するか? A. 例えば 0 10 255 を指定したとする しかし 代表値 最小値 最大値だけでは欠陥が検出できない可能性がある 26

3-2 [ 事例 2] オーバーフローに誘発されたゼロ割処理 例 ) 演算後に除算している場合 検出できない欠陥とポイント long func(unsigned char arg1) { :: a = (b / (unsigned char)(arg1 + 5)); :: } この演算処理において ゼロ割を発生させる値が 1 点だけ存在する arg2 に 251 を与えた場合のみ +5 するとオーバーフローするため 除算の分母が 0 になり ゼロ割が発生する ポイント特定の値を与えられた場合のみ欠陥となるコードがあることを認識してテストを行う コードを見ないと有効なテストができないケースもあり得ることを認識する 27

4. ユニットテストまとめ 28

4 ユニットテストまとめ 品質の良いユニットテストのために必要なもの ユニットテストの位置づけについての正しい理解 ( 特にソースコードレビューとの違い ) ユニットテストは開発において非常に重要な工程だが 正しい知識を持って実施できていることが少ない テストケース設計の知識いかに有用なテストケースを作るかが重要 テストデータの与え方の知識テストケースが正しくても 与えるテストデータによって欠陥が検出できるかできないかが決まる 3つの知識が揃って始めて 品質の良いユニットテストができる ただし 3つの知識をOJTだけで習得するのは難しい Off-JT で3つの知識を習得する必要がある 29

単体テスト関連サービスについて 単体テスト教育 単体テストはどの開発プロジェクトでも実施しますが 明確に実施方法が定まっていません そんな開発現場で活用してもらうために単体テストに特化した教育コンテンツを揃えています C 言語版 C++ 言語版 のコンテンツがあります 本コンテンツを使用したセミナーを定期的に開催しています 主催 ガイオ テクノロジー株式会社 URL : http://www.gaio.co.jp/event/event.html 単体テスト代行サービス ソフトウェア品質を確保するために重要な工程である 単体テスト を代行します ブラックボックス ホワイトボックス ロバスト性の観点から 高品質な単体テストを実施します 単体テスト代行サービスの効果に不安がある場合 試験的に数関数に対して単体テスト代行サービスを実施することも可能です ガイオ テクノロジー株式会社の単体テスト代行サービスを支援しております テスト導入支援 テスト導入支援は単体テスト以外の内容もカバーしたサービスです 単体テスト以外 ( 設計や結合テスト ) の工程も改善しなければソフトウェア品質が向上しない場合 お客様の現場に合った方法をご提案します 例 テストガイドライン策定 テスト設計レビュー 設計書確認 ガイオ テクノロジー株式会社のテスト導入支援を支援しております ご質問 ご相談 資料請求はこちらまで : emb-sales@nskint.co.jp 30

単体テスト以外 (Android) のサービスについて Android アプリケーション開発初級編 Android OS の基礎知識を学ぶとともに Android アプリケーション開発の基本となるプログラミングモデルを講義と実習から習得します Android アプリケーション開発応用編 Android の中枢であるアプリケーションフレームワークの仕組みを理解するとともに 実際の Android アプリケーション開発でよく発生する問題点の事例 解決策などを理解することで より高度な Android アプリケーション開発のスキルを習得します Android 開発ポーティング編 ターゲットボード上の Linux システム上に Android 特有のドライバの構築と ミドルウェア Android アプリケーション等の搭載を行います また Android のチューニング技術なども習得する事により 実践的な Android 技術者の育成が可能になります ( 企画 : 株式会社エンベデッド システム開発 : 日本システム開発株式会社 ) その他必要スキル教育 (Java, デザインパターン等 ) 株式会社豆蔵との連携により Android 開発に必要なその他技術要素の習得も可能です (Java, デザインパターン,, UML 等 ) ご質問 ご相談 資料請求はこちらまで : emb-sales@nskint.co.jp 31

御清聴ありがとうございました 32