Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit test of flex bison scanner parse, how to drive the test case

I have a question about how to "drive" a flex bison based parser scanner in a unit test.

The final solution will be a command parser available or telnet to a target board. I have a fully working flex bison implementation using stdin.

Right now my focus is on getting a unit test running for the command parser.

I would like to be able to provide a "const string" to the parser (a command) and then test that the corresponding command is invoked in the application (in a application stub).

I do not know how to setup flex and bison for this. Please find the test case below:

status_cmd_test.c:

#include "CUnit/Basic.h"
#include "cmd_stub.h"


void scan_string(const char* str);

void testSTATUS_OK(void)
{

  scan_string("status\n\0\0");
  CU_ASSERT(1 == status_sub_nrof_invokes())

}

Excerpt from cmd_lexer.l:

void scan_string(const char* str)
{
  YY_BUFFER_STATE buf;
  buf = yy_scan_string(str);
  yylex();
  yy_delete_buffer(buf);
}

cmd_parser.y does not contain any c-code, only bison grammar.

Excerpt from cmd_test.c (has the int main() where the cunit code is located)

if (NULL == CU_add_test(suite_p, "test of status", testSTATUS_OK))
{
  CU_cleanup_registry();
  return CU_get_error();
}

/* Run all tests using the CUnit Basic interface */
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
CU_cleanup_registry();
return CU_get_error();

I have tried to understand the documentation by I do not know how to drive bison ( yyparse() or something like that).

Can anyone give me a hint?

/ Mikael

like image 886
rmcarlsson Avatar asked Mar 05 '14 18:03

rmcarlsson


People also ask

What are the unit test case preparation guidelines for unit testing?

Unit Testing Test Case Preparation Guidelines: 1. Unit Test Plan/Cases should be made a separate deliverable. It should not be merged with other artifacts. Try to document all the probable test scenarios which encompasses uncommon and alternative flows.

How does a flex generated scanner work?

The flex generated scanner code tries to match characters from the current input stream to these regular expressions, and when a match is found, it executes the associated action code. The variable yytext contains the string (in the C sense, i.e. null-terminated char array) of characters that were matched.

What is the difference between unit testing and functional testing?

Unit testing tests the units of your code by isolating individual parts of the software. On the other hand, functional testing tests the whole program functions according to the user requirements. #2. Unit testing code is easy to write plus execute for the next step. It comes under the white-box technique.

How to assign a variable to yylval in bison?

You will need to add a new line to the %union part of the bison file. Then open the scanner file and use the strdup function as discussed above to actually assign to yylval . Now just go back and modify the code for the grammar rule that does assignment to use the actual variable name (semantic value) instead of "x" or whatever you used.


1 Answers

I see this question has remained unanswered for nearly a year and is the OP's only question. It's possibly an interesting question covering elements of potentially incompatible technologies. It also contains some incorrect assertions that give a false view of the solution space.

First its worth summarising what is being asked. Cunit is a unit testing library that permits the instrumentation on C code for automated unit testing. Unit testing is usually testing code units in the absence of a user interface. Flex and Bison are tools used to construct language based interfaces.

Language based interfaces are usually tested using file input based automated testing, rather than unit based testing; however the software functions invoked by the interface might be unit tested. Yet unit testing may have a role in testing software written with flex and bison.

The question states that the parser source file does not contain any C code, only grammar. This must be incorrect, because if it contained only grammar and no semantic actions then the language would do nothing. The running of the parser would have no action of any kind but display an error message or not, which is a user interface function. To have any value a parser must invoke semantic actions which would be written in some language, often C. These multiple and important piece of C code could be instrumented for unit testing.

As asked in the question, to unit test with Cunit, the flex/bison coded interface would have to use parameterised input and output instead of the file/stream input output.

This can be achieved. There are quite a few other answers on SO that refer to how this can be done (as well as the flex/bison manuals). If we want to test using string input we can substitute string input for file input as discussed here:

  1. Is there working example of flex + bison with input from string, not file?
  2. How to make YY_INPUT point to a string rather than stdin in Lex & Yacc (Solaris)
  3. how to use yy_scan_string in lex
  4. how to parse from a string rather than a file

Similarly the output of bison can be captured by redefining yyerror and other reconfigurable interfaces, but I wont list the questions that discuss those.

So, in summary, yes - it is possible. Is it sensible. I'm not sure. My feeling is there are enough other forms of automated testing tools more suited to language based interface components.

like image 199
Brian Tompsett - 汤莱恩 Avatar answered Sep 20 '22 03:09

Brian Tompsett - 汤莱恩