美文网首页
使用ReactJS+babel+Bulma CSS构建测试报告页

使用ReactJS+babel+Bulma CSS构建测试报告页

作者: FredricZhu | 来源:发表于2024-05-19 19:32 被阅读0次

测试过程中,会有需要将Test Report以各种样式呈现的需求。
本例使用ReactJS + babel + Bulma CSS呈现带菜单和分类的静态测试报告页面。
这种方式可以使数据和报告分离。
使用不同的data.js文件,可以展示不同的测试报告。
程序输出的样例报告效果如下,


image.png

程序代码如下,
index.html

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Bifang工程测试报告</title>  
    <script src="./src/lib/react-development.js"></script>
    <script src="./src/lib/react-dom.development.js"></script> 
    <script src="./src/lib/babel.min.js"></script>  
    <link rel="stylesheet" href="./css/bulma/bulma.min.css">
</head>  
<body>  
    <div id="main"></div>

    <script src="./data.js" type="text/javascript"></script>
    <script type="text/babel">  

        class ChannelInfo extends React.Component {
            constructor(props) {
                super(props)
            }
            
            render() {
                return (<div>
                    <table className="table" border={0} style={ {width: "100%"} }>
                            <tbody>
                                <tr>
                                    <th> topic name </th>
                                    <td>{this.props.channel["topic_name"]}</td>
                                </tr>
                             
                                <tr>
                                    <th> Messages </th>
                                    <td>
                                        <ul>
                                            {this.props.channel["messages"].map(
                                                (msg, i) =>
                                                <li key={i}>
                                                    <span className="subtitle is-6"> 
                                                        {JSON.stringify(msg)}
                                                    </span>
                                                </li>
                                            )}
                                        </ul>
                                    </td>
                                </tr>

                            </tbody>
                    </table>
                </div>)
            }

        }



        class PageContent extends React.Component {
            constructor(props) {
                super(props)
                this.state = {
                    display: false
                }
            }

            setDisplay() {
                this.setState({display: !this.state.display})
            }

            render() {
                return (<div className="block">
                            <div onClick={() => this.setDisplay()}>
                                <table class="table">
                                    <tr>
                                        <td><abbr title="Position">{this.props.content["descriptions"]["case_id"]}.</abbr></td>
                                        <td>{this.props.content["descriptions"]["case_name"]}</td>
                                    </tr>
                                </table>
                            </div>

                            <h2 className="is-5" style={this.state.display? {}: {display: "none"}}>
                                <table className="table">
                                    <thead>
                                        <tr>
                                            <th><abbr title="Title">Title</abbr></th>
                                            <th>Content</th>
                                        </tr>
                                    </thead>
                                    
                                    <tbody>
                                        <tr>
                                            <th>Description</th>
                                            <td>
                                                <li> Test Case ID : { this.props.content["descriptions"]["case_id"] } </li>
                                                <li> Case Name : { this.props.content["descriptions"]["case_name"]} </li>
                                                <li> Validation Type: { this.props.content["validate_type"] } </li>
                                            </td>
                                        </tr>

                                        <tr>
                                            <th>Passed</th>
                                            {this.props.content["passed"]? 
                                                <td className="is-success"> Yes </td>: 
                                                <td className="is-danger"> NO </td>
                                            }
                                        </tr>


                                        <tr>
                                        <th> Input Messages </th>
                                        {
                                            
                                            this.props.content["input"].map(
                                            (channel, i) =>
                                                <tr>
                                                    <td key={i}><ChannelInfo channel={channel} /></td>
                                                </tr>
                                            )
                                        }
                                        </tr>

                                        <tr>
                                        <th> Output Messages </th>
                                        {
                                            
                                            this.props.content["actual"].map(
                                            (channel, i) =>
                                                <tr>
                                                    <td key={i}><ChannelInfo channel={channel} /></td>
                                                </tr>
                                            )
                                        }
                                        </tr>


                                        <tr>
                                        <th> Expect Messages </th>
                                        {
                                            
                                            this.props.content["expectation"].map(
                                            (channel, i) =>
                                                <tr>
                                                    <td key={i}><ChannelInfo channel={channel} /></td>
                                                </tr>
                                            )
                                        }
                                        </tr>

                                        <tr>
                                            <th>
                                                Test Result
                                            </th>
                                            <td>
                                                <span className="subtitle is-6" dangerouslySetInnerHTML={{__html: this.props.content["result_info"].replace("\n", "<p>")}} />
                                            </td>
                                        </tr>
                                        
                                   
                                    </tbody>
                                
                                </table>
                            </h2>

                    </div>)   
            }
        }

        class MainPage extends React.Component {
            constructor(props) {
                super(props)
                console.log("DATA==")
                console.log(this.props.data)
                this.state = {
                    case_st: "FAIL",
                    page: "UIUE"
                }
            }

            setPage = (page_) => {
                this.setState({page: page_})
            }

            setCaseStatus= (status_) => {
                console.log("Set case Status!")
                this.setState({case_st: status_})
            }

            renderHeader = () => {
               
                if(this.state.page && this.props.data.hasOwnProperty(this.state.page)) {
                        return (
                        <div className="tile is-ancestor columns">
                            <div className="tile is-parent column is-4">
                                <article className={this.state.case_st === "FAIL"? "tile is-child notification is-danger": "tile is-child notification" }  onClick={() => this.setCaseStatus("FAIL")}>
                                
                                <p className="subtitle">FAILED</p>
                                <p className="subtitle">{this.props.data[this.state.page]["failed"]}</p>
                                </article>
                            </div>
                        
                                <div className="tile is-parent column is-4">
                                    <article className={this.state.case_st === "PASS"? "tile is-child notification is-danger": "tile is-child notification" }  onClick={()=>this.setCaseStatus("PASS")}>
                                    <p className="subtitle">Passed</p>
                                    <p className="subtitle">{this.props.data[this.state.page]["passed"]}</p>
                                    </article>
                                </div>
                        
                            <div className="tile is-parent column is-4">
                                <article className="tile is-child notification">
                                <p className="subtitle">Pass Rate</p>
                                <p className="subtitle">{this.props.data[this.state.page]["pass_rate"]}</p>
                                </article>
                            </div>
                    </div>
                    )
                }   
            }

            renderBody = (bodyData) => {
                    return (<div className="block">
                            {bodyData.map((test_case, i) =>
                                <PageContent key={i} content={test_case} />
                            )}
                        </div>
                    )   
            }


            render() {

                return (
                    
                <div className="columns">
                <div className="column is-2">
                            <div className="block">
                                <aside className="menu">
                                    <p className="menu-label">测试报告</p>
                                    <ul className="menu-list">
                                        <li> <a onClick={() => this.setPage("UIUE")} className={this.state.page === "UIUE" ? "is-active": ""}>UIUE模块</a></li>
                                        <li> <a onClick={() => this.setPage("ParkingFus")} className={this.state.page === "ParkingFus" ? "is-active": ""}>ParkingFus模块</a></li>
                                    </ul>
                                </aside>
                        </div>
                    </div>
                    
                    <div className="block column is-9">
                        {this.renderHeader()}
                        {  
                            this.state.case_st === "FAIL" ? this.renderBody(this.props.data[this.state.page]["failed_cases"]):
                             this.renderBody(this.props.data[this.state.page]["passed_cases"])
                        }
                    </div>
                </div>
                )
            }
        }

        class App extends React.Component {
            constructor(props) {
                super(props)
            }

            render() {
                return (<div className="container" >
                          <MainPage data={this.props.data}/>            
                    </div>)
            }
        }

        ReactDOM.render(
            <App data={js_obj}/>,
            document.getElementById('main')
        );
    </script>
</body>  
</html>

data.js文件如下,

let js_obj = {
    "ParkingFus": {
        "passed_cases": [
            {
                "passed": true,
                "descriptions": {
                    "case_id": 1,
                    "case_name": "ParkingFus全景开启,软按键开启"
                },
                "input": [
                    {
                        "topic_name": "Send_Topic_name",
                        "messages": [
                            {
                                "struct": "SendCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 1
                            },
                            {
                                "struct": "SendVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 2
                            }
                        ]
                    },
                    {
                        "topic_name": "Send_Topic_name_2",
                        "messages": [
                            {
                                "struct": "SendCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "SendVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 4
                            }
                        ]
                    }
                ],
                "validate_type": "log|msg",
                "expectation": [
                    {
                        "topic_name": "Rec_Topic_name",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 1
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 2
                            }
                        ]
                    },
                    {
                        "topic_name": "Rec_Topic_name_2",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 4
                            }
                        ]
                    }
                ],
                "actual": [
                    {
                        "topic_name": "Rec_Topic_name",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 1
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 2
                            }
                        ]
                    },
                    {
                        "topic_name": "Rec_Topic_name_2",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 4
                            }
                        ]
                    }
                ],
                "result_info": "Msg equal passed\nLog equal passed\n"
            }
        ],
        "failed_cases": [
            {
                "passed": false,
                "descriptions": {
                    "case_id": 2,
                    "case_name": "ParkingFus全景开启,软按键开启"
                },
                "input": [
                    {
                        "topic_name": "Send_Topic_name",
                        "messages": [
                            {
                                "struct": "SendCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 1
                            },
                            {
                                "struct": "SendVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 2
                            }
                        ]
                    },
                    {
                        "topic_name": "Send_Topic_name_2",
                        "messages": [
                            {
                                "struct": "SendCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "SendVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 4
                            }
                        ]
                    }
                ],
                "validate_type": "log|msg",
                "expectation": [
                    {
                        "topic_name": "Rec_Topic_name",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 2
                            }
                        ]
                    },
                    {
                        "topic_name": "Rec_Topic_name_2",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 4
                            }
                        ]
                    }
                ],
                "actual": [
                    {
                        "topic_name": "Rec_Topic_name",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 1
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 2
                            }
                        ]
                    },
                    {
                        "topic_name": "Rec_Topic_name_2",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 4
                            }
                        ]
                    }
                ],
                "result_info": "Msg equal passed\nLog equal passed\n"
            }
        ],
        "passed": 1,
        "failed": 1,
        "pass_rate": "50.0%"
    },
    "UIUE": {
        "passed_cases": [
            {
                "passed": true,
                "descriptions": {
                    "case_id": 1,
                    "case_name": "UIUE全景开启,软按键开启"
                },
                "input": [
                    {
                        "topic_name": "Send_Topic_name",
                        "messages": [
                            {
                                "struct": "SendCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 1
                            },
                            {
                                "struct": "SendVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 2
                            }
                        ]
                    },
                    {
                        "topic_name": "Send_Topic_name_2",
                        "messages": [
                            {
                                "struct": "SendCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "SendVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 4
                            }
                        ]
                    }
                ],
                "validate_type": "log|msg",
                "expectation": [
                    {
                        "topic_name": "Rec_Topic_name",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 1
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 2
                            }
                        ]
                    },
                    {
                        "topic_name": "Rec_Topic_name_2",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 4
                            }
                        ]
                    }
                ],
                "actual": [
                    {
                        "topic_name": "Rec_Topic_name",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 1
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 2
                            }
                        ]
                    },
                    {
                        "topic_name": "Rec_Topic_name_2",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 4
                            }
                        ]
                    }
                ],
                "result_info": "Msg equal passed\nLog equal passed\n"
            }
        ],
        "failed_cases": [
            {
                "passed": false,
                "descriptions": {
                    "case_id": 2,
                    "case_name": "UIUE全景开启,软按键开启"
                },
                "input": [
                    {
                        "topic_name": "Send_Topic_name",
                        "messages": [
                            {
                                "struct": "SendCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 1
                            },
                            {
                                "struct": "SendVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 2
                            }
                        ]
                    },
                    {
                        "topic_name": "Send_Topic_name_2",
                        "messages": [
                            {
                                "struct": "SendCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "SendVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 4
                            }
                        ]
                    }
                ],
                "validate_type": "log|msg",
                "expectation": [
                    {
                        "topic_name": "Rec_Topic_name",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 2
                            }
                        ]
                    },
                    {
                        "topic_name": "Rec_Topic_name_2",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 4
                            }
                        ]
                    }
                ],
                "actual": [
                    {
                        "topic_name": "Rec_Topic_name",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 1
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 2
                            }
                        ]
                    },
                    {
                        "topic_name": "Rec_Topic_name_2",
                        "messages": [
                            {
                                "struct": "RecvCSC_APA_Req_Fusion_Struct",
                                "Get_Something_uint8": 3
                            },
                            {
                                "struct": "RecvVDL_APA_Req_Fusion_Struct",
                                "Set_Something_uint8": 4
                            }
                        ]
                    }
                ],
                "result_info": "Msg equal passed\nLog equal passed\n"
            }
        ],
        "passed": 1,
        "failed": 1,
        "pass_rate": "50.0%"
    }
}

其中使用的react-development.js,react-dom.development.js, babel.min.js和bulma.min.css可以到网上进行下载。是通用的css和js文件。

相关文章

网友评论

      本文标题:使用ReactJS+babel+Bulma CSS构建测试报告页

      本文链接:https://www.haomeiwen.com/subject/enknfjtx.html