Tag Archives: requirement based testing

Tips of Requirements and design using statecharts formalism(Statecharts formalism를 이용한 요구사항 및 설계 작성 tip)


korean version is below. 한국어버전은 아래로

This was introduced at the DO-178C certification consulting meeting, and I hope that this will probably be helpful to others. In DO-178C, there is no clear separation criterion for the requirements and design description steps. Also, the human brain does not think separately of requirements and design explanations. Quite capable programmers often think about the logic of the code while writing requirements. I consider the possibility of verifying the test environment, test method, test case, etc. of this requirement while reviewing the requirements.

My client decided to express the requirements as statecharts in the project for DO-178C certification. The diagram that the customer expressed has various problems in my judgment. Although it was one of the main research fields at the graduate school, it described the specification method even though it was a long time.

Statecharts is a visual formalism devised by David Harel as an extended version of the FSM (Finite state machine). Statecharts has since been incorporated into UML, and has been transformed from Simulink in Mathworks into the notation Stateflow.

(For another moment, statecharts has a non-determinism attribute, a troublesome issue in AI, so to develop a fatalistic system, Mathworks invented a deterministic version of statecharts, Stateflow.)

(Of course, the diagram you are trying to express is meant to be deterministic.)

Components of Statecharts

Statecharts = {S, s0, I, O, T}.

S = set of states
S0 = initial state
I = set of input variables
O = set of output variables
T = S x Cond1 x Cond2 x S The set of state transitions,
Where Cond1 = state transition condition, Cond2 = state transition behavior
Although the mathematical definition of transition is a bit old, it is not perfect, but let’s skip this once.

With all the elements defined above, the above Statecharts can be implemented, executable, and can generate test cases.

For example, suppose you have the following Statecharts

S = {s0, S1, s2}
I = {i1, i2}
O = {o1, o2}
T = {t1, t2}
T1: = {s0, ‘i1 = 1’, ‘o1 = 1’, s1}

T2: = {s1, ‘i2 = 0’, ‘o1 = 0, o2 = 1’, s2}

For developers, this can be done directly in code. In the past, when I participated in the model review and refactoring of projects that automatically generated auto code in stateflow (remember that time). With a few frameworks, it is possible to generate code mechanically without using expensive tools . The following code can be different from the behavior of the actual statecharts when run instead of applying the framework. I just want to understand it as a concept.

State = s0;
While (1)
{
Switch (State)
S0:
If (i1 == 1) {o1 = 1; State = s1; Break;}
Break;
S1:

For tester making test procedure, you can make test procedure by making the following table.

Test prefix for state reachability

S0: null
S1: null. “I1 = 1”
S2: null. “I1 = 1”. “I2 = 0”
The meaning of the above notation means that it is necessary to keep it in the initial state to reach s0. In order to reach s1, 1 is inputted to i1 in the initial state. In case of s2, i1 = 1 is inputted in the initial state And then enter 0 in i2.

I think the test procedure for the transition in each state is understandable enough without saying a word.

So, let’s take the eternal questions of DO-178C beginners.

Drawing with Statecharts, I think I draw requirements and designs together, how do I separate them?

I do not know if it needs to be separated, but if you split it off and decide that you need to write some in the Software Requirement Data (SRD) and some in the DD (Design Description), you can hierarchically represent the statecharts, Slice. It is a purely personal judgment to which level to slice, and I do not think DER will blame it for being wrong.

Note that even if you do not express requirements and designs with statecharts, you can still use vertical logical slicing to represent your requirements in a hierarchical way, even if they are expressed in natural language. Therefore, the upper level can be classified into HLR (high level requirement) and the lower level can be divided into LLR (low level requirement).

If I explained this, I think I got enough sense. I hope to use it in practice now.

What if you still do not know? You need to get consulting services, so please contact me. In the meantime, there have been a lot of examples that have impressed customers with the high-quality expression of experts, so if you have difficulty in expressing it, you may be assisted by a consultant, like me.

DO-178C 인증 컨설팅 회의때 있었던 일인데, 다른 사람들에게 도움이 될 듯 하여 소개를 해볼까 한다. DO-178C에서 요구사항과 설계 설명 단계는 칼로 무 자르듯이 명쾌한 분리기준이 존재하지 않는다. 또한 인간의 뇌는 요구사항과 설계 설명 단계를 별도로 분리하여 생각하지 않는다. 꽤 유능한 개발자들은 대부분 요구사항을 작성하면서 코드의 로직까지 생각한다. 나같은 경우는 요구사항을 검토하면서 이 요구사항의 시험 환경, 시험 방법, 시험 케이스 등의 검증 가능성을 생각하지만..

고객은 요구사항을 statecharts로 표현하기로 했다. 고객이 표현한 diagram은 내가 볼때 여러가지 문제가 있었다. 대학원 박사과정때 주 연구분야중의 하나였기 때문에 오래되긴 했지만, specification방법에 대해서 기술했다.

Statecharts는 David Harel에 의해 고안된 visual formalism으로서 FSM(Finite state machine)의 extended version이라고 볼 수 있다. Statecharts는 이후 UML에도 통합되었고, Mathworks의 Simulink에서 Stateflow라는 표기법으로 변형되기도 했다.

(잠깐 다른 이야기를 하자면, statecharts가 최근 AI에서 핫한 non-determinism 속성을 갖고 있기 때문이다. 그래서 운명론적인 시스템을 개발하기 위해 Mathworks에서는 deterministic version의 statecharts를 창안하게 된 것이고, 그래서 탄생하게 된 것이 Stateflow이다.)

(물론 고객이 표현하려는 diagram에서는 deterministic한 행동을 하도록 표현되어 있다.)

Statecharts의 구성요소

Statecharts = {S , s0, I, O, T} 로 정의된다.

  • S = 상태의 집합
  • S0 = 초기 상태
  • I = 입력 변수의 집합
  • O = 출력 변수의 집합
  • T = S x Cond1 x Cond2 x S 상태 천이의 집합,
    여기서 Cond1 = 상태 전이 조건, Cond2 = 상태 전이 행동

Transition에 대한 수학적 정의가 오래되어서 살짝 완벽하지 않은 감이 있기는 하지만, 일단 이 정도로 하고 넘어가겠음.

위에서 정의한 모든 요소를 갖추면 위 Statecharts는 구현 가능하며, executable하며, test case를 생성할 수 있다.

예를 들어 다음과 같은 Statecharts가 있다고 가정해보자

S = {s0, S1, s2}
I = {i1, i2}
O = {o1, o2}
T = {t1, t2}

t1: = {s0 , ‘i1=1’ , ‘o1=1’, s1}

t2:={s1, ‘i2=0’, ‘o1=0, o2=1’,s2}

개발자 입장에서는 이 것만 보고 코드로 바로 구현이 가능하다. 예전에 stateflow에서 자동으로 auto code를 생성하는 프로젝트의 모델 검토 및 리팩토링에 참여했을 당시 (그 때 쯤이었던 것으로 기억한다.) 약간의 framework만 있으면 비싼 툴을 사용하지 않고도 기계적으로 code 생성하는 것이 가능하다. 아래의 코드에는 그런 framework가 적용된 것이 아니라 실행시켜보면 실제 statecharts의 behavior와 다를 수 있다. 그저 concept정도로만 이해했으면 한다.

State = s0;
while(1)
{
switch(State)
s0:
if (i1==1) {o1=1; State = s1; break;}
break;
s1:

시험 절차를 만드는 tester입장에서는 다음의 table을 만들어서 test procedure를 만들 수 있다.

state reachability를 위한 test prefix

s0: null
s1: null.”i1=1″
s2: null.”i1=1″.”i2=0″

위 표기방식의 의미는 s0에 도달하기 위해서는 초기상태에서 가만히 있으면 된다는 의미고, s1에 도달하기 위해서는 초기상태에서 i1에 1을 입력하면 도달하게 되며, s2의 경우는 초기상태에서 i1=1을 입력하고 그 이후 i2에 0을 입력하면 도달한다.

각 상태에서의 transition에 대한 test procedure는 굳이 말하지 않아도 충분히 이해할 수 있을 것이라고 생각한다.

자, 그렇다면 DO-178C 초심자들의 영원한 질문사항을 받아보도록 하겠다.

Statecharts로 그리면 요구사항 및 설계를 같이 그리는 거 같은데, 어떻게 분리해야 하는가?

딱히 분리를 해야 할 필요가 있을지는 모르겠으나, 굳이 분리를 해서 일부는 SRD(Software Requirement Data)에 기술하고 일부는 DD(Design Description)에 기술해야겠다고 판단한다면, statecharts를 hierarchical하게 표현하고, 그것을 vertical하게 slice한다. 어느 level을 slice하는지는 순수하게 개인적인 판단이며, 그거 잘못했다고 DER이 비난하지는 않을 것이라고 생각한다.

참고로 굳이 statecharts로 요구사항 및 설계를 표현하지 않는다고 하더라도, natural language로 표현한다고 하더라도 철처한 logical thinking process를 적용해서 요구사항을 hierarchical하게 표현하여 마찬가지로 vertical slice를 할 수도 있다. 그래서 상위 level을 HLR(high level requirement), 하위 level을 LLR(Low level requirement)로 구분지을 수도 있다.

이정도 설명했으면 충분히 감을 잡았으리라 생각한다. 이제 실전에서 활용해보기 바란다.

아직도 잘 모르겠다면? 컨설팅 서비스를 받아야 할 필요가 있으므로, 나에게 연락하기 바람. 그동안 전문가의 고급스러운 표현으로 고객을 감동시킨 사례가 많이 있었으므로, 표현하는데 어려움이 있다면 컨설턴트의 도움을 받아도 좋음.

Advertisements

Unit testing is useless in some aspects(단위 시험은 어떤 측면에서 쓸데없다)


한글버전은 아래로..

I think the title is somewhat irritating. I admit it. It is an exaggerated expression. But it is also true.

I think there is nothing better than a unit test. It is a very good practice if you have completed the unit test to see if you are doing what you intended to do.

But if you think about the quality of the product by a third party, the position will change. In a real consulting project, I found that it is quite tricky for a third party auditor to make a technical assessment of this part.

That’s true.

When we say that the coverage measurement is not a coverage analysis, the unit test ‘s uselessness shines. For example, suppose you create a calculator program that has an add / subtract function. In terms of coverage, 1 + 1, 1-1, 1/1, 1 * 1 will achieve 100% by default.

But …. Do you think you will use the test procedure and write the test results in a normal unit test? Or do you think you will see the test results and change the test procedure? Eh ? What are you talking about?

In the process, it is important to write a test procedure, to test it, to get test results, and to review the results. But ……………. There might be a developer who does not …

It is possible to use a trick somewhat different from the intended direction in the standard. However, the problem is that it is very difficult to carry out a technical examination of this part in the case of a unit test. Is it possible for a third party assessor to understand and check the logic of your code ?

What’s even worse is that there is a shortcut to achieve this if you have a goal to achieve 100% of MC / DC as well as code coverage … This is not the intention of the person who originally thought of this method.

This leads to the conclusion that it is not possible to check whether the unit test was carried out with authenticity. It is not that much if it is aimed at making sure that one trick is properly passed through one by one. Besides, it’s hard for the assessor to catch that part.

If then, why we have to force unit test?

In that respect, the requirement based test method overcomes this problem. In addition, it is possible to check how well the requirements are written, and the examination of the test procedures and the results of those parts can be better done.

From that point of view, standards that require unit testing need to be refreshed

 

제목이 약간 자극적이라는 생각이 든다. 인정한다. 과장된 표현이다. 하지만, 사실이기도 하다.

단위 시험을 제대로 한다면 그것만큼 훌륭한 툴은 없다고 생각한다. 설계자의 의도에 맞는 행동을 하는지의 여부를 단위시험까지 완벽하게 되었다면 매우 훌륭한 practice임에는 틀림이 없다.

하지만 제3자가 그 제품에 대한 quality를 평가해야 하는 입장에서 생각해보면 입장이 달라진다. 실제 컨설팅 프로젝트에서 이 부분에 대해 제 3자 auditor가 이 부분에 대한 기술적인 평가를 하는 것이 상당히 까다롭다는 것을 발견했다.

실제로 그렇다.

coverage analysis가 아닌 coverage 측정 행위를 한다고 했을때, unit 시험의 무용론은 빛을 발하게 된다. 예를 들어 가감승제 기능이 있는 연산기 프로그램을 만든다고 가정하자. coverage 관점에서 1+1, 1-1, 1/1, 1*1을 하면 기본적으로 100%를 달성하게 될 것이다.

그런데…. 보통의 단위 시험을 시험 절차를 쓰고 시험 결과를 쓴다고 생각하는가? 아니면 시험 결과 나온 것을 보고 시험 절차를 변경한다고 생각하는가? 엥 ? 이게 무슨 소리냐고?

프로세스 상으로는 시험 절차를 쓰고, 시험을 해서 시험 결과가 나오고, 그 결과를 검토하는 것이 정석이다. 그런데……………. 그렇게 하지 않는 개발업체도 있을 수 있다는 말이다…

표준에서 의도했던 방향과는 약간 다르게 trick을 쓸 수 있는 것이다. 그런데, 문제는 단위 시험의 경우 이 부분에 대한 기술적 검토를 하는 것이 굉장히 어렵다는 것이다. 코드의 로직을 다 이해하고 점검해야 하는데, 과연 제 3자 평가자가 그 정도까지 할까?

게다가 더 최악인 점은…. Code coverage뿐만 아니라 MC/DC까지도 100%를 달성하고자 하는 목표만 있다면, 이를 달성하기 위한 지름길이 있다는 점이다… 이 또한 당초 이 방법을 생각한 사람의 의도한 것이 아닐 것이다.

상황이 이렇다보니 unit test에 대한 진정성을 가지고 수행했는지에 대한 점검이 원천적으로 불가능하다는 결론에 다다르게 된다. 어차피 꼼수로 하나 제대로 하나 통과받도록 하기 위한 목적이라면 별것도 아니라는 얘기다. 게다가 평가자가 그 부분을 잡기도 힘들고..

그럴거면 unit test라는 것을 왜 억지로 하도록 해야 하냐 이거다.

그런 점에서 requirement based test방법은 이런 문제점을 극복한다. 게다가 requirement가 얼마나 잘 작성되었는지를 점검할 수도 있으며, 그 부분에 대한 시험 절차와 결과의 검토가 더 잘 이루어질 수 있다.

그런점에서 봤을때, unit test를 요구하는 표준들은 좀 반성을 해야 할 필요가 있다고 생각한다…

 

Unit testing을 요구하는 표준과 그렇지 않은 표준


Unit level의 testing을 요구하는 표준이 있고, 그렇지 않은 표준이 있다. 둘간에 별 차이가 없을 거라고 생각할지도 모르겠다. 어차피 사람이 하는 일이고, 사람마다 눈 두 개 달려 있고, 손 두 개 달려있으니, 그게 그거 아니겠는가? 하고 말이다.

Automotive SPICE와 ISO26262의 경우에는 unit level의 testing을 요구하는 반면, DO-178C나 DO-278A에서는 그런 요건이 존재하지 않는다. 다만 요구사항 기반으로 시험을 하라고 요구한다.

재밌는것은 unit level의 testing을 요구하는 자동차쪽 domain에서 test case를 추출하는 기법으로 requirement based testing을 요구하고 있다는 점이다.

요구사항 관점에서 설계를 하거나 구현을 할 때, 두 가지 구현 방식이 있을 수 있다. 하나는 architecture를 설계하고 그 설계에서 component를 설계하고 그 안의 unit을 설계해서 구현하는 방식이 있다. 이 방식은 수직적 방식으로 계층적 구조를 지닌다.

다른 하나는 수평적 방법으로 요구사항에 대한 sub요구사항을 만들어서 그 요구사항에 대한 로직을 설계해서 구현하는 방식이다. 이 방식은 수평적 방식으로 볼 수 있다.

수직적 설계 방식을 적용했을 때, 요구사항에서 architecture로의 trace를 해 보았는가? 해 보았다면 과연 그게 쉬웠는가?

만약 가능하다고 대답하고 싶다면, 그 application의 경우 그럴 수 있다고 생각하고, 일반적인 경우에 대해 가능하냐고 묻고 싶다. In general, is it possible ?

이는 불가능하다고 생각한다.

그런 방식에서는 요구사항에 대한 추적이 쉽지 않다.

예를 들어서 사람의 인체로 설명을 해보자.

사람을 물리적으로 나눈다면 5장 6부가 있다. (곤충을 머리, 가슴, 배로 나누듯이) 그런데 인간의 걷는 기능과 관련된 인체 내의 part와의 관계(추적성)는 어떻게 맺을 수 있을까? 인간의 먹거나 자는 기능과 관련된 추적성은 어떻게 맺을 수 있을까?

연관이 없는게 없다고 하기도 뭣하고, 하나만 연관짓기도 뭣하고…참으로 거시기 할 것이다.

일반적으로 인체의 5장 6부로 구조화 한것은 인간이 수행할 수 있는 여러가지 기능(or activity)별로 쪼갠것이 아니다. 일반적으로 system level의 function은 sub-system(5장 6부)의 유기적인 interaction과 process에 의해 달성되기 때문이다.

sub-system(5장 6부)의 기능은 system level의 function에 1:1로 매핑되지 않는것과 같이, 그리고 그러한 방식으로 architect 되지 않았듯이, 일반적으로 sw설계에서도 그러하다.

다른 방식으로 다시 설명을 해보자면, software architecture로 넘어와서 crosscutting block의 경우 requirement기반의 기능과 mapping시킨다고 할 때, 혹은 middleware level을 설계했을때, 이를 requirement와 mapping시킨다고 했을때, 그게 쉬운가?

진짜로 쉬운가? 진심으로? 정말로? 혼또니 ?

그럴리 없다.

정말 어려운 일이다.

 

결론이다. unit level testing은 최상위 요구사항에 대해 mapping하는 것은 매우매우 어렵다.
unit level testing을 하려면 sw architecture를 설계해야 한다.하지만 모든 sw가 architecture를 필요로 하는 것은 아니라고 생각한다. architecture를 설계할때의 장단점이 있을 뿐, 그게 없다고 sw가 안되거나 하진 않는다. ISO26262의 sw개발 concept과 DO-178C의 sw 개발 concept이 같다고 생각하겠지만, 실상은 그렇지 않다. (비슷해 보일 수는 있을지라도 같은 것은 아님)

나는 개인적으로 DO-178C쪽의 표준이 더 잘 정의되었고, best practice로서 적용하기도 좋다고 생각한다.

그렇다고 자동차쪽 sw개발 방식을 비판했다거나 뭐 그런것도 아니다.

어떤 approach건 pros와 cons는 존재하기 마련이다.

그리고 그러한 방식이 잘 맞는 application이 있기 마련이다.

세상에 silver bullet이란 건 없다.

만약 존재한다면 그것은 매우 가격이 높아서 공학적으로 가치가 없을 것이다.
(그런 의미에서 효용성이 없어서 silver bullet이 없다는 의미도 된다.)