ソフトウェアテスト技法練習帳 デシジョンテーブル2_01 一杯目のビールの価格 学習メモ

# 概要
## 投稿理由
・ソフトウェアテスト技法練習帳でデシジョンテーブルについて勉強したので記録に残します。
  内容はCodepenで動く実物と設計書（もどき）です。

## 対象読者
・ソフトウェアテストのデシジョンテーブルの例を確認したい方。プロダクトコードとテストコードを確認できます。

## 工夫したこと
・動作環境はブラウザのみする
　情報共有をしやすくしたいため、プログラマ以外の端末でも動作環境を確保できるようにする。
　極力docker,node.jsなどを動作環境に含めたくない。
 　（テストコードの動作環境はdocker有り）
 
・プロダクトコードは動けば良いというレベルで実装しています。そこまで力入れてません。


## デシジョンテーブルとは
```
デシジョンテーブルを使用して論理的な条件をカバーし、
入出力の組み合わせを規則ごとに実行するテストケースを設計するテスト
```

https://service.shiftinc.jp/column/4950/

# 成果物
## codepen
ビジネスルールに基づいて、一杯目の価格を決める。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="KwPmrRX" data-pen-title="software_test_2_01" data-user="rya234" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/rya234/pen/KwPmrRX">
  software_test_2_01</a> by RYA234 (<a href="https://codepen.io/rya234">@rya234</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

## プロダクトコード

動作環境

名称|version|説明
---|--------|---
GoogleChrome|131.0.6778.86|ウェブブラウザ


```html
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>2_1 一杯目のビールの価格</title>
</head>
<body>
    <h1>2_1 一杯目のビールの価格</h1>
    <div>
        <div>
            <input type="checkbox" id="happyHour" name="happyHour" />
            <label for="happyHour">ハッピーアワー</label>
        </div>
        <div>
            <input type="checkbox" id="coupon" name="coupon" />
            <label for="coupon">クーポン</label>
        </div>
    </div>
    <button id="run">計算</button>
    <div id="result" style="color:red;"></div>
<script>
    let currentEnchant = [0,0,0,0];
    const maxEnchant = [0,0,0,1];
    const  weapon_id =["hinoki","ninjin","kikori","kusanagi"];

    // event 系
window.onload = (event) => {

    const coupon = document.getElementById('coupon');
    const happyHour = document.getElementById('happyHour');
    const button = document.getElementById('run');
    const result = document.getElementById('result');
    
    const normalPrice = 490;
    const couponPrice = 100;
    const happyHourPrice = 290;

    // ボタンクリック時の処理
    button.addEventListener('click', event => {
        console.log(happyHour.checked);
        if(coupon.checked){
            result.innerHTML = "結果: " + (couponPrice ) + "円です。";
            return
        }
        if(happyHour.checked){
            result.innerHTML = "結果: " + (happyHourPrice) + "円です。";
            return
        }
        result.innerHTML = "結果: " + (normalPrice) + "円です。";
    });
}
</script>
</body>
</html>
```


## テストコード

開発環境
名称|version|説明
---|--------|---
Javascript|-|プログラミング言語
HTML|HTML Living Standard|GUI
docker|27.0.3-1|コンテナ型仮想環境
Nodejs|22.9.0|単体テスト実行で使う
Jest|29.70|テストフレームワーク
jsdom|25.01|DOM操作のライブラリ　テストで使う
Github Codespaces|-|クラウドIDE


```js
// import {fromFile} from '@testing-library/jsdom';
import { test } from '@jest/globals';
import fs from "fs/promises";
import { JSDOM } from "jsdom";
// 実行コマンド
// docker-compose exec -it webserver bash -c  "npm test 2_01.test.js"
// 参考にしたやつ
// https://symfoware.blog.fc2.com/blog-entry-2685.html

;
describe('1_07 武器の強化判定', () => {

  let html="";
  let dom = ""
  beforeEach(async() => {
    html = await fs.readFile("software_test/02Decision_Table/2_01/2_01.html")
    dom =  new JSDOM(html,{runScripts: "dangerously"});
    dom.window.onload();
  })

  test.each([
    [false,false,"490"],
    [true,true,"100"],
    [true,false,"290"],
    [false,true,"100"],
  ])('２択＊２のデシジョンテスト', async(isHappyHour,isCoupon,expectedResult) => {
        
       // テキスト入力欄を取得し値を設定
        const button = dom.window.document.getElementById('run');
        const happyHoursCheckBox = dom.window.document.getElementById("happyHour");
        const couponCheckBox = dom.window.document.getElementById("coupon");
        const result = dom.window.document.getElementById('result');
        happyHoursCheckBox.checked = isHappyHour;
        couponCheckBox.checked = isCoupon;
        // クリック
        button.click();
        // 結果の取得
        expect(result.innerHTML).toContain(expectedResult);
  });

});


```



# ドキュメント

## ユースケース記述
項目名|説明
--|---
ユースケース|１杯目のビールの価格を求める
主アクター|ユーザ
事前条件|なし
主シナリオ|１．入力欄を記入 </br> ２．ボタンを押す</br>価格を確認する
成功時保証|--
ビジネスルール|通常価格、クーポン割引、ハッピーアワー割引、価格の優先度について




## ビジネスルール
項目名|説明
--|---
ビジネスルール名|通常価格
内容|490円/杯

項目名|説明
--|---
ビジネスルール名|クーポン割引
内容|初めの一杯のみ100円

項目名|説明
--|---
ビジネスルール名|ハッピーアワー割引
内容|290円/杯

項目名|説明
--|---
ビジネスルール名|価格の優先度について
内容|最も安い値段を優先する



## 画面項目

項目名|表示名|I/O|プロパティ(物理名)|種類|備考
-----|-----|---|--------|---|---
タイトル|１杯目のビールの価格|O|title|ラベル| _|
ハッピーアワー|--|I|happyHour|チェックボックス| _|
クーポン|--|I|coupon|チェックボックス| _|
実行|計算|I|run|ボタン| clickイベント有り|
結果|結果：XXX|O|result|ラベル|clickイベント実行後に値が変化する|


## イベント処理

### ボタン　onClickイベント
　入力項目に対して、入力規則を満たしているか確認する。
　頻繁に使うので、クライアントで実行

```plantuml
@startuml
title button click event
autonumber
actor user

box HTML
participant text as "input"
participant Button as "button"
participant output as "result"

endBOX
box javascript
 participant event
 participant logic

 
 user --> text:input radiobox
 user --> Button:pressButton
 activate event
 Button --> event:call event handler
    event -> logic :  set input
    logic -> event : return result
    event --> output :  display result

 deactivate event
endbox
@enduml

```




ライフライン名|分類|説明
------------|----|---
input|HTML|id=happyYear  couponに該当
button|HTML|id=runが該当
result|HTML|id= resultに相当
event|JS| Clickイベントハンドラー
logic|JS| ビジネスルール ４種

# ノートに書いた下書き
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/9679dce3-bd0e-f4b4-e99c-3f991afb0754.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/c5ae65fb-aae3-8822-6885-2f61e5dae21f.png)




# 参考

github 差分
https://github.com/RYA234/routine_tool/commit/11eb85c46d79e01fb878ebe12d4b8fde4708b003

テスト観点

https://qiita.com/nittannittan/items/2d8a342a8d77db53b70a

「はじめての設計をやり抜くための本　第２版」　p95 ユースケース分析

qiitaにCodepenを埋め込む
https://qiita.com/Qiita/items/edae7417214c8e957f54

「ソフトウェアテスト技法練習帳 ~知識を経験に変える40問」