ソフトウェアテスト技法練習帳_同値分割1_7_武器の強化判定

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

## 対象読者
・ソフトウェアテストの同値分割法の例を確認したい方。プロダクトコードとテストコードを確認できます。

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

# 成果物

## codepen


<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="vEBmdPv" data-pen-title="software_test_1_07" 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/vEBmdPv">
  software_test_1_07</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>1_7 武器の強化判定</title>
</head>
<body>
    <h1>1_7 武器の強化判定</h1>
    <div id="message_area" style="color:red;"> </div>
    <div>
        <div>
            <input type="radio" id="hinoki" name="weapon" value="0" />
            <label for="hinoki">ひのきの棒</label>
        </div>
        <div>
            <input type="radio" id="ninjin" name="weapon" value="1" />
            <label for="ninjin">にんじんの短剣</label>
        </div>
        <div>
            <input type="radio" id="kikori" name="weapon" value="2" />
            <label for="kikori">きこりの大斧</label>
        </div>
        <div>
            <input type="radio" id="kusanagi" name="weapon" value="3" />
            <label for="kusanagi">草薙の槍</label>
        </div>
    </div>
    <button id="run">強化</button>
<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 messageArea = document.getElementById('message_area');
    const button = document.getElementById('run');
    // const textBox= document.get('weapon');
    const result = document.getElementById('result');
    // ボタンクリック時の処理
    button.addEventListener('click', event => {
        messageArea.innerHTML = "";
        // 武器強化
        if(currentEnchant[getRadioBoxValue()] == maxEnchant[getRadioBoxValue()]){
            messageArea.innerHTML = "結果:強化限界です。";
            return;
        }

        currentEnchant[getRadioBoxValue()] = 1;
        messageArea.innerHTML = "結果:強化しました。";
        const weapon_name= document.getElementById(weapon_id[getRadioBoxValue()]);
        document.getElementsByTagName("label")[parseInt(getRadioBoxValue())].innerHTML +=  "  強化済み";
    });
}


function getRadioBoxValue(){
        // ラジオボタンの取得
        let elements = document.getElementsByName('weapon');
        let len = elements.length;
        let checkValue = '';
        for (let i = 0; i < len; i++){
            if (elements.item(i).checked){
                checkValue = elements.item(i).value;
            }
        }
        console.log(checkValue);
        return checkValue;
}

</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 1_07.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/01Equivalence_Partitioning/1_07/1_07.html")
    dom =  new JSDOM(html,{runScripts: "dangerously"});
    dom.window.onload();
  })

  test.each([
    ["hinoki",1,"結果:強化限界です。"],
    ["kusanagi",1,"結果:強化しました。"],
    ["kusanagi",2,"結果:強化限界です"],
  ])('単体テスト"', async(actualWeapon,clickCount,expectedResult) => {
        
       // テキスト入力欄を取得し値を設定
        const button = dom.window.document.getElementById('run');
        const selectedWeapon = dom.window.document.getElementById(actualWeapon);
        const message_area = dom.window.document.getElementById('message_area');
        selectedWeapon.checked = true;
        
        // クリック
        for(let i=0;i < clickCount; i++){
          await button.click();
        }
        // 結果の取得
        expect(message_area.innerHTML).toContain(expectedResult);
  });

});

```



# ドキュメント

## ユースケース記述
項目名|説明
--|---
ユースケース|武器を強化する
主アクター|　ユーザー
事前条件| --
主シナリオ| ・武器を選択する <br/>・武器を強化する
成功時保証| --
ビジネスルール| 武器強化ルール



## ビジネスルール
項目名|説明
--|---
ビジネスルール名|武器強化ルール
内容|武器には３種類ある <br/> 強化可能、強化済み、強化不可 </br>強化可能を１回強化すると強化済みになる<br/>強化済みは強化できない


強化可能の武器：くさなぎの武器
強化不可の武器：けやきのぼう、ニンジンの短剣、木こりの大斧


## 画面項目

項目名|表示名|I/O|プロパティ(物理名)|種類|備考
-----|-----|---|--------|---|---
タイトル|武器判定|O|title|ラベル| _|
武器リスト|--|I|name=weapon|ラジオボタン|--|
実行|強化する|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=weaponに該当
button|HTML|id=runが該当
message|HTML|id= resultに相当
event|JS| Clickイベントハンドラー
logic|JS| ビジネスルール「武器強化ルール」：

# ノートに書いた下書き
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/7f3635f6-b4fe-d276-5521-894a694ff559.png)



# 参考

github 差分
https://github.com/RYA234/routine_tool/commit/03f92b425b0e10e0916f3a87c2a3250e89582556




テスト観点

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

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

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

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