310 likes | 449 Views
1 Hui Wu, 1 Jeff Gray and 2 Marjan Mernik 1 University of Alabama at Birmingham, USA {wuh,gray}@cis.uab.edu 2 University of Maribor, Slovenia marjan.mernik@uni-mb.si. Unit Testing for Domain-Specific Languages. DSL 2009 Oxford, UK July 15, 2009. Programming Methodologies Laboratory.
E N D
1Hui Wu, 1Jeff Gray and 2Marjan Mernik 1University of Alabama at Birmingham, USA {wuh,gray}@cis.uab.edu 2University of Maribor, Slovenia marjan.mernik@uni-mb.si Unit Testing for Domain-Specific Languages DSL 2009 Oxford, UK July 15, 2009 Programming Methodologies Laboratory
Emperors New DSLs But where are the tools I can use? • As we show off our new DSLs and approaches for creating them, are there some obvious limitations that we may be ignoring?
OOPSLA 2008 DSL Panel:The Good, the Bad, and the Ugly • Four of the five participants listed lack of tool support as a top challenge for DSLs • Utility of a new DSL is severely diminished if supporting tools needed by a software developer and/or end-user are not available • Poor interoperability and reuse of such tools
What Kinds of Tools are Needed? Editor Compiler Domain Experts program at DSL level Domain Experts deal with GPL Visualizer Debugger Profiler DSL translated into General Purpose Language (GPL) Integrated Development Environment (IDE) Domain Experts deal with DSL Test Engine 4
Mismatch Between Abstraction Levels Generated Java Parser Code ANTLR Grammar …. public final void commands() throws RecognitionException, TokenStreamException { try { // for error handling { switch ( LA(1)) { case CALL: case INIT: case SET: case PRINT: { command(); commands(); break; } case END: { break; } default: { throw new NoViableAltException(LT(1), getFilename()); … public final void function_name() throws RecognitionException, TokenStreamException { try { // for error handling { switch ( LA(1)) { case RIGHT: { match(RIGHT); fileio.print(" //move right"); fileio.print(" move_right();"); fileio.print(" "); break; } case LEFT: { match(LEFT); sllinenumber=dsllinenumber+1; fileio.print(" //move left"); fileio.print(" move_left();"); fileio.print(" "); break; } … …. commands : ( c:command cs:commands | ) ; command : ( RIGHT { fileio.print("//move right"); fileio.print("x=x+1;"); fileio.print("time=time+1;"); fileio.print(" "); } |LEFT { fileio.print("//move left"); fileio.print("x=x-1;"); fileio.print("time=time+1;"); fileio.print(" "); … 5
Why is basic DSL tool support lacking? • Example • ANTLRStudiohttp://www.placidsystems.com/antlrstudio.aspx • Fixed tool support customized for specific DSL • Why are such tools scarce? • Building new DSL tools from scratch for each new DSL can be time consuming, error prone and costly • Tooling implementation effort generally not reusable for a different context (even in same domain)
Idea of this paper • Introduce the idea of a framework for building DSL tools that reuse existing GPL tools • Assumptions/Limitations: • Only applicable to source-to-source translation (DSL reuses GPL compiler and other tools of GPL context) • DSL tool implementation dependent on available GPL mappings; requires adaptation to existing grammars • Does not consider case when one DSL statement is mapped to non-contiguous GPL code (e.g., an aspect language) • Paper uses simple examples for illustration; scalability of approach not certain
DSL to GPL Source Mapping {13, "Robot.java", 20, 21, "main", "none"} 8
Background Context: DSL Debuggers • Our initial work for DSL tool support focused on debuggers • The DSL Debugging Framework (DDF) provides a context for understanding the source mapping necessary to reuse GPL tools in a DSL context
Debugging Results Mapping:Tangled Concerns within Grammar Black: Basic functionality Blue: Source code mapping Red: Debugging results mapping 12
Imperative DSL Debugger Variables defined in terms of DSL, not GPL User has access to traditional debugging operations 13
Declarative DSL Debugger (FDL) 1 Car : all (Carbody, Transmission, Engine, Horsepower, opt(pullsTrailer)) 2 Transmission : oneof(automatic, manual) 3 Engine : moreof (electric, gasoline) 4 Horsepower : oneof (lowPower, mediumPower, highPower) 5 include pullsTrailer 6 pullsTrailer requires highPower 14
Current Focus: DSL Testing • Before locating software errors how do we know there are bugs inside a DSL program?
DSL Unit Testing Framework (DUTF) • Complement to the DSL Debug Framework (DDF) – the DUTF assists in identifying the presence of errors and the DDF assists in isolating the specific location of the error • Architecture and process of construction is similar to the DDF architecture (Figure 1 in paper); source code mapping similar 19
DSL Unit Testing Framework (DUTF):Test Cases Mapping {1, “TestRobot.java”,11,“testknight”} • A testing assertion at the DSL level may result in multiple assertions at the GPL level depending on variable mapping 21
DSL Unit Testing Framework (DUTF)Robot Language Unit Test Engine User sees results as typical JUnit test report, but with DSL test cases 23
Video Demonstration • DUTF Testing Demo 2.1 available at http://www.cis.uab.edu/softcom/DDF/
Adapting Existing DSL Grammars for DSL Tool Support • Crosscutting concerns emerge in different software artifacts (e.g., model, grammar, and source code) • AspectG: A domain-specific aspect language for language grammars written in ANTLR • Program transformation rules are generated from a domain-specific aspect language focused on language specification in ANTLR • Generated rules modify grammars, not source code 26
Addition of DSL Tool Support: A Crosscutting Grammar Concern Base Grammar … command :( RIGHT { fileio.print(" //move right"); fileio.print(" x=x+1;"); fileio.print(" time=time+1;"); fileio.print(" "); } |LEFT { fileio.print(" //move left"); fileio.print(" x=x-1;"); fileio.print(" time=time+1;"); fileio.print(" "); } | … What if this line changes? Change here Duplicate Tool Aspect Code dsllinenumber=dsllinenumber+1; gplbeginline=fileio.getLinenumber(); gplendline=fileio.getLinenumber(); filemap.print(" mapping.add(new Map("+dsllinenumber+", \"Robot.java\","+gplbeginline+","+gplendline+"));"); dsllinenumber=dsllinenumber+1; gplbeginline=fileio.getLinenumber(); gplendline=fileio.getLinenumber(); filemap.print(" mapping.add(new Map("+dsllinenumber+", \"Robot.java\","+gplbeginline+","+gplendline+"));"); Change here Change …… 27
Join Point Model for AspectG ANTLR Grammar AspectG … command :( RIGHT { dsllinenumber=dsllinenumber+1; fileio.print("x=x+1;"); gplbeginline=fileio.getLinenumber(); fileio.print("time=time+1;"); gplendline=fileio.getLinenumber(); fileio.print(" "); filemap.print(" mapping.add(new Map("+ dsllinenumber+", \"Robot.java\","+gplbeginline+ ","+gplendline+"));"); } … pointcutproductions(): within(command.*); pointcut count_gpllinenumber(): within(command.*) && match (fileio.print("time=time+1;")); before(): productions() {dsllinenumber=dsllinenumber+1;} before(): count_gpllinenumber() {gplbeginline=fileio.getLinenumber();} after(): count_gpllinenumber() {gplendline=fileio.getLinenumber();} after(): productions() {filemap.print(" mapping.add(new Map("+ dsllinenumber+", \"Robot.java\","+gplbeginline+ ","+gplendline+"));"); } 28
Summary and Lessons Learned • Tool development requires deep understanding of DSL, our framework, and the required mappings • JUnit tests for equality in assertion checks may not match semantics of domain and need to be adapted • Among 22 software components in DUTF, there are 3,001 lines of code that are generalized and can be reused to generate different DSL unit test engines 29
Future Work An extension of the current framework that enables DSL profiling Adaptation of DUTF to address more complex DSLs Investigation into extending DUTF to other platforms Application of different IDE platforms (Microsoft Visual Studio .Net) and GPLs (C# and C++) using Nunit and other testing tools 30 30
Programming Methodologies Laboratory Acknowledgement: The work presented in this paper was supported in part by NSF CAREER grant (CCF-0643725) and the IBM Eclipse Innovation Grant (EIG). Video demonstrations and papers available at: http://www.cis.uab.edu/softcom/DDF/ Questions? 31