0% found this document useful (0 votes)
4K views41 pages

Introduction To Reqt: - A Free Software Requirements Modeling Tool

reqT is a free software requirements modeling tool that allows users to: - Create and manage scalable requirements models using collections and natural language expressions. - Auto-generate requirements documents from models for publishing. - Perform scripting of models using an internal Scala DSL.

Uploaded by

ravirajrbk
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4K views41 pages

Introduction To Reqt: - A Free Software Requirements Modeling Tool

reqT is a free software requirements modeling tool that allows users to: - Create and manage scalable requirements models using collections and natural language expressions. - Auto-generate requirements documents from models for publishing. - Perform scripting of models using an internal Scala DSL.

Uploaded by

ravirajrbk
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 41

- a free software requirements modeling tool reqT.org LundUniversity.lu.

se

Introduction to reqT

Last changed: Feb 13, 2013

What can you do with reqT?


You can ... create & manage scalable requirements models using versatile collections combine natural language expressiveness with type-safe modeling interoperate with spread sheet applications auto-generate requirements documents for web publishing do powerful scripting of requirements models with the reqT internal Scala DSL

reqT Gist
var m = Model( Product("reqT") has Gist("A tool for modeling evolving requirements."), Release("2.0") has Gist("Major update based on student feedback."), Product("reqT") owns Release("2.0") ) m += Feature("toHtml") has Gist("Generate web document.") println(m) m.toHtml.save("reqT.html")

Feature("toHtml")

Create your own document templates


val myTemplate = DocumentTemplate( "Requirements Document", Text("Generated by " + " <a href=\"http://reqT.org\">reqT.org</a> " + ( new java.util.Date ) ), Chapter("Context", Text(""), m => m / Context), Chapter("Features", Text(""), m => m / Feature) ) m.toHtml(myTemplate).save("reqT.html")

Feature("toTable")

Model.fromTable("reqT.txt")

How to run reqT


You can run reqT in several ways: Kojo - an interactive environment for Scala scripting http://kogics.net/sf:kojo Scala REPL command line Read-EvaluatePrint-Loop http://typesafe.com/stack In your own pre-compiled Scala application For more details on how to download & install reqT into Kojo or Scala, see reqT.org/download

Why is reqT built in Scala?


Platform-independent and efficient (JVM) Flying start if you know some Java Statically typed: help to locate bugs early Statically typed: fast and efficient programs Type inference: less verbose Flexible syntax: good for internal DSL Interactive scripting: rapid trialing & feedback Scalability: from small scripts to large systems Free open source, academic control (EPFL), EU support with commercial backup (typesafe.com )

Modeling requirements with reqT


A reqT model includes sequences of graph parts <Entity> <Edge> <NodeSet> separated by comma and wrapped inside a Model( ) A small reqT Model with Entities (three Features one Stakeholder) and Edges (has, requires, assigns) and related sets of nodes (either attributes or other entities):
Model( Feature("f1") has (Spec("A good spec."), Status(SPECIFIED)), Feature("f1") requires (Feature("f2"), Feature("f3")), Stakeholder("s1") assigns(Prio(1)) to Feature("f2") )

Implied reqT graph structure


Model( Feature("f1") has (Spec("A good spec."), Status(SPECIFIED)), Feature("f1") requires (Feature("f2"), Feature("f3")), Stakeholder("s1") assigns(Prio(1)) to Feature("f2") )

requires Feature ("f3") requires Feature ("f1")


has has

Feature ("f2")
Status

Spec

assigns(Prio(1)) Stakeholder("s1")

Different types of Requirement entities in reqT


Requirement Goal Feature Function Data Quality Interface Design Scenario Class Member UserStory UseCase Task VividScenario

Different types of Context entities in reqT

Context Product Release Stakeholder Actor

Different types of Relations in reqT


Relation owns requires excludes helps hurts precedes inherits deprecates assigns(Attribute)

Special relationship for hierarchical decomposition

Expressing interdependencies in reqT


An and-relation is equivalent to two mutual requires-relations: Feature("printer.X") requires Feature("driver.Y") Feature("driver.Y") requires Feature("printer.X") Sometimes a requires-relation is non-mutual: Feature("sendEmail") requires Feature("networkAccess") Temporal relations regarding a preferred implementation order can be expressed using a precedes-relation: Function("add") precedes Function("delete") Mutual exclusion (xor) can be expressed using two mutual excludes-relations: Design("centralized") excludes Design("distributed") Design("distributed") excludes Design("centralized") Entities that support or hinder each other are modeled using hurts and helps relations : Goal("secure") helps Goal("safe") Goal("secure") hurts Goal("simple")

[Some examples modified from Carlshamre, P., Sandahl, K., Lindvall, M., Regnell, B., Natt och Dag: "An industrial survey of requirements interdependencies in software product release planning", J.: Int. Conf. on Requirements Engineering (RE01), Toronto, Canada, pp. 8491, 2001]

Expressing release allocation in reqT


The result of release planning can be expressed in reqT using requires-relations between Release and Requirement entities:
Model( Product("p") Release("A") Release("B") Release("A") Release("B") ) owns (Release("A"), Release("B"), Release("C")), precedes Release("B"), precedes Release("C"), requires (Feature("a"),Feature("b"),Feature("c")), requires (Feature("d"),Feature("e"),Feature("f"))

Future versions of reqT may include constraints to formulate and solve release planning problems using Constraint Satisfaction Programming (CSP) with a CSP solver (e.g. JaCoP)

Different types of Attributes in reqT


Attribute[T](value: T) Gist(String) Spec(String) Status(Level) Why(String) Example(String) Input(String) Output(String) Prio(Int) Label(String) Image(String) Trigger(String) Precond(String) Frequency(String) Critical(String) Problem(String) Comment(String) Deprecated(String)

reqT.Goal example
Goals are high-level reasons for creating products or features.
Model( Product("shipyard quoting") has Spec("Ship repair cost calculations based on experience data."), Goal("increase accuracy") has Spec("Our precalculations shall be more accurate than today."), Product("shipyard quoting") helps Goal("increase accuracy") )

[Example modified from Lauesen: "Software Requirements Styles and Techniques"]

reqT.Feature example
A feature is a releasable characteristic of a Product.
Model( Feature("room repair") has ( Gist("Manage room repair periods."), Spec("The product shall be able to " + "record that a room is under repair in a specified period." + "When under repair, the room shall not be bookable."), Status(SPECIFIED) ) )

[Example modified from Lauesen: "Software Requirements Styles and Techniques"]

reqT.org Status promotion levels


up

up

RELEASED
up

TESTED
down

down

IMPLEMENTED
up down

up

PLANNED
up up down

FAILED

VALIDATED
up down init up down

POSTPONED
down

down

SPECIFIED

ELICITED

down

DROPPED
up

down

Status(value: Level)
scala> val s = Status.init s: reqT.Status = Status(ELICITED) scala> s.up res1: reqT.Status = Status(SPECIFIED) scala> s.down res2: reqT.Status = Status(DROPPED)

up RELEASED up TESTED up IMPLEMENTED up down down

up PLANNED up VALIDATED down

down FAILED up down

up init up ELICITED down SPECIFIED

down

POSTPONED down

down up

DROPPED

down

Creating and updating Status in reqT


scala> var m = Model(Feature("x") has Status.init, Feature("y") has Status.init) m: reqT.Model = Model( Feature("x") has Status(ELICITED), Feature("y") has Status(ELICITED) ) scala> m.up res8: reqT.Model = Model( Feature("x") has Status(SPECIFIED), Feature("y") has Status(SPECIFIED) ) scala> m = (m / Feature("x")).up ++ (m \ Feature("x")) m: reqT.Model = Model( Feature("x") has Status(SPECIFIED), Feature("y") has Status(ELICITED) ) scala> m = m up Feature("x") //equivalent shorter way to do previous

restrict operator aggregate operator exclude operator

Priorities
Any entity can have an integer priority attribute:
Model( Feature("x") has Prio(10), UserStory("u") has Prio(20), Stakeholder("s") has Prio(5) )

Priotities can also be expressed as relations between entities:


Model( Stakeholder("s") assigns(Prio(5)) to Feature("x"), Stakeholder("s") assigns(Prio(1)) to Feature("y"), Stakeholder("s") assigns(Prio(9)) to Feature("z") )

reqT Data requirement example


Model( Class("Guest") has ( Gist("Pays the bill."), Spec("The guest is the person or company who has to pay the bill. A guest has one or more stay records. 'Customer' is a synonym for guest but in the database we only use 'guest'. The persons staying in the rooms are also called guests but are not guests in database terms."), Example("(1) A guest who stays one night. (2) A company with employees staying now and then each of them with his own stay record where his name is recorded. (3) A guest with several rooms within the same stay.") ), Member("name") has Spec("Text, 50 chars. The name stated by the guest. For companies the official name since the bill is sent there. Longer names exist but better truncate at registration time than at print out time."), Member("passport") has Spec("Text 12 chars. Recorded for guests who are obviously foreigners. Used for police reports in case the guest does not pay."), Class("Guest") owns (Member("name"), Member("passport")) )

[Example modified from Lauesen: "Software Requirements Styles and Techniques"]

reqT Data Model example


Model( Class("Guest") assigns(Label("1:m")) to Class("Stay"), Class("Stay") assigns(Label("1:m")) to Class("RoomState"), Class("Room") assigns(Label("1:m")) to Class("RoomState"), Function("Room database") has Image("ER-diagram.png"), Function("Room state") has Image("room-state-diagram.png") )

[Example modified from Lauesen: "Software Requirements Styles and Techniques"]

reqT Image example


Model( Function("guest data") has ( Spec("The product shall store guest data according to virtual window 'create guest data'."), Image("create-guest-data.png") ) )

[Example modified from Lauesen: "Software Requirements Styles and Techniques"]

reqT Context diagram example


Model( Product("Hotel system") owns ( Interface("ReceptionUI"), Interface("GuestUI"), Interface("TelephonyAPI"), Interface("AccountingAPI") ), Product("Hotel system") has Image("context-diagram.png"), Interface("ReceptionUI") has ( Input("booking, check-out"), Output("service note"), Image("recetionUI-screen.png") ), Interface("GuestUI") has ( Output("confirmation, invoice"), Image("guestUI-screen.png")), Actor("Receptionist") requires Interface("ReceptionUI"), Actor("Guest") requires Interface("GuestUI"), Actor("Receptionist") requires Interface("ReceptionUI"), Actor("Telephony System") requires Interface("TelephonyAPI"), Actor("Accounting System") requires Interface("AccountingAPI") )
[Example modified from Lauesen: "Software Requirements Styles and Techniques"]

reqT Task description example


Model( Task("reception work") owns (Task("check in"), Task("booking")), Task("check in") has ( Why("Give guest a room. Mark it as occupied. Start account."), Trigger("A guest arrives"), Frequency("Average 0.5 checkins/room/day"), Critical("Group tour with 50 guests.") ), Task("check in") owns ( Task("find room"), Task("record guest"), Task("deliver key")), Task("record guest") has Spec( "variants: a) Guest has booked in advance, b) No suitable room" ) )

[Example modified from Lauesen: "Software Requirements Styles and Techniques"]

reqT Quality requirement examples


Model( Quality("capacity database") has Spec("#guests < 10,000 growing 20% per year, #rooms < 1,000"), Quality("accuracy calendar") has Spec("Bookings shall be possible at least two years ahead."), Quality("performance forecast") has Spec("Product shall compute a room occupation forecast within ___ minutes. (Customer expects one minute.)"), Quality("usability task time") has Spec("Novice users shall perform tasks Q and R in 15 minutes. Experienced users tasks Q, R, S in 2 minutes."), Quality("usability task time") requires (Task("Q"), Task("R"), Task("S")) Quality("performance peak load") has Spec("Product shall be able to process 100 payment transactions per second in peak load.") )

[Examples modified from Lauesen: "Software Requirements Styles and Techniques"]

reqT QUPER example


var m = Model( UserStory("playMusic") has Spec("As a user I want to play music."), UserStory("playMusic") requires Quality("timeToMusic"), Quality("performance") owns (Quality("timeToMusic"), Quality("timeToVideo")), Quality("timeToMusic.metric") has Spec("Measured in seconds using tests XYZ."), Quality("timeToMusic.ref.X") has (Spec("4.0 s"), Comment("Competitor product X.")), Quality("timeToMusic.ref.Y") has (Spec("2.0 s"), Comment("Competitor product Y.")), Quality("timeToMusic.ref.Z") has (Spec("3.0 s"), Comment("Our own released product Z.")), Quality("timeToMusic.utility") has Spec("5.0 s"), Quality("timeToMusic.differentiation") has Spec("1.5 s"), Quality("timeToMusic.saturation") has Spec("0.2 s"), Quality("timeToMusic.barrier.1") has Spec("2.0 s requires Effort(Range(4,5),Weeks)"), Quality("timeToMusic.barrier.2") has Spec("1.0 s requires Effort(Range(24,48),Weeks)"), Quality("timeToMusic.target.min") has (Spec("2.0 s"), "Actual" requirements given Comment("Probably possible with existing architecture.")), meaning by this model Quality("timeToMusic.target.max") has (Spec("1.0 s"), Comment("Probably needs new architecture.")), Quality("timeToMusic") has Image("QUPER-timeToMusic.jpg") )

[Example modified from "Setting quality targets for coming releases with QUPER: an industrial case study", R. Berntsson Svensson, Y. Sprockel, B. Regnell, S. Brinkkemper, Requirements Engineering, DOI: 10.1007/s00766-011-0125-0]

Sources & destinations in reqT graph structures


Model( Feature("f1") requires (Feature("f2"), Feature("f3")), Stakeholder("s1") assigns(Prio(1)) to Feature("f2") ) requires Feature ("f3") Feature ("f1") sources Stakeholder ("s1") requires Feature ("f2") destinations

assigns(Prio(1))

Add, Restrict, Exclude, Split, Aggregate


var m = Model() m += Feature("hello") has Spec("print da stuff") m += Feature("f1") has (Gist("g1"), Spec("s1")) m += Feature("f1") has Gist("g2") m += Product("p1") owns (Feature("f1"), Feature("hello")) var m2 = m Feature("f1") m / Feature("f1") m / Feature m / Spec m / Context m / Feature / Gist m /+ Feature("f1") m \ Feature val (m1, m2) = m | Feature m ++ m2 m + Gist("same same") Create an empty model. Add an entity with one attribute. Add an entity with several attributes. Adding existing attributes overwrites old. Add a relation. "Owns" is a special relation that enforces hierarchical decomposition. Remove an entity also in relations. A restriction returns a new Model that is a submodel including only some elements. Entity types can be used to restrict the submodel to any element of that type. Attributes can also be used in restrictions. Restriction on an abstract type. Restrictions can be stacked. An extended restriction returns a submodel including also related nodes. An exclusion gives everything but this. A partition gives a pair with a model split: (m / Feature, m \ Feature) Aggregate two models. Add the same attribute to all entities.

reqT script for adding owns-relations


var m = Model( /* QUPER example from previous slide */) scala> val s = "timeToMusic" s: java.lang.String = timeToMusic scala> val ttm = Quality(s) ttm: reqT.Quality = Quality(timeToMusic) scala> val ttms = m / (s + ".") sources

ttms: Set[reqT.Entity] = Set(Quality(timeToMusic/target/min), Quality(timeToMusic/metric), Quality(timeToMusic/barrier/2), Quality(timeToMusic/ref/X), Quality(timeToMusic/ref/Y), Quality(timeToMusic/ref/Z), Quality(timeToMusic/differentiation), Quality(timeToMusic/utility), Quality(timeToMusic/saturation), Quality(timeToMusic/target/max), Quality(timeToMusic/barrier/1))

scala> m += ttm.owns(ttms.toArray:_*)

reqT.org types
Abstract
subtype

Element

scala.collection.immutable.Map[Key, NodeSet] Model

Concept Node Attribute[T](value: T) Gist(String) Context Product Release Class Member UserStory UseCase Task VividScenario Stakeholder Actor Spec(String) Status(Level) Why(String) Example(String) Input(String) Output(String) Prio(Int) Label(String) Image(String) Edge

Structure Key(Entity, Edge) NodeSet(Node, Node, ...) AttributeEdge Relation has owns requires Trigger(String) Precond(String) Frequency(String) Critical(String) Problem(String) Comment(String) Deprecated(String) excludes helps hurts precedes inherits deprecates assigns(Attribute)

Type

Entity(id: String) Requirement Goal Feature Function Data Quality Interface Design Scenario

Very short intro to Scala syntax


Similar to Java, but types are placed after identifiers with colon but not needed if they can be inferred by the compiler
val s1: String = "hello" val s2 = "hello" // type String is inferred and not needed

Functions are objects and can be passed as values


def f(x: Int) = 2 * x // function definition scala> List(1,2,3).map(f) // passed as argument to map function res0: List[Int] = List(2, 4, 6) scala> List(1,2,3).map(x => 2 * x) // unnamed function literal res1: List[Int] = List(2, 4, 6) scala> List(1,2,3).map(2 * _) // short form: placeholder parameter res2: List[Int] = List(2, 4, 6)

Syntax is flexible: you can skip dots and parentheses in some cases
"abc" + "xyz" // string concatenation, short for: scala> "abc".+("xyz") // object.method(singleParameter) res3: java.lang.String = abcxyz

Scala tutorial for Java programmers: http://docs.scala-lang.org/tutorials/

What can you do with a Scala Map?


You can associate keys with values in Maps to get an associate array for fast element retrieval:
scala> var m = Map("dog" -> 84, "cat" -> 42, "bird" -> 21) m: scala.collection.immutable.Map[java.lang.String,Int] = Map(dog -> 84, cat -> 42, bird -> 21) scala> m("cat") res10: Int = 42

Maps are efficient and have many useful operations: http://docs.scala-lang.org/overviews/collections/maps.html

Boosting your requirements models with the power of Scala collections


A reqT Model is a map of Key(Entity, Edge) -> NodeSet
class Model( val mappings: scala.collection.immutable.SortedMap(Key, NodeSet) ) extends scala.collection.immutable.Map(Key, NodeSet)

scala> val kns = Feature("f") has (Gist("g"), Spec("s"), Prio(1)) kns: (reqT.Key, reqT.NodeSet) = (Key(Feature(f),has()),NodeSet(Gist(g), Spec(s), Prio(1))) scala> Model(kns) res42: reqT.Model = Model(Feature("f") has ( Gist("g"), Spec("s"), Prio(1) ) )

Example use of powerful Scala scripting: Collecting and looping with guards
// extract all entities that have priority < 5 val highPrio: Model = m collect { case (Key(entity,edge), nodes) if nodes exists { case Prio(p) => p < 5 case _ => false } => (Key(entity,edge), nodes) } // do the same with a for-comprehension val highPrio: Model = for ( (Key(entity,edge), nodes) <- m if nodes exists { case Prio(p) => p < 5 case _ => false } ) yield (Key(entity,edge), nodes)

Extracting attributes from models


var m = Model( Feature("f1") has (Gist("g1"), Spec("s1")), Feature("f2") has Gist("g2") ) val s = m ! Gist val s2 = m / Feature("f2") ! Gist s2 match { case Some(str) => println(str) case None => } s2.foreach(println) val s3 = m / Feature("f2") ! Spec s: Option[String] = Some(g1) s2: Option[String] = Some(g2) g2 Extract some Gist: Get the string of the first Gist in m. Get the string of the Gist of f2 If s is Some[String] then print it, else if s is None then do nothing.

g2 s3: Option[String] = None s4: String = g1 s5: String = UNDEFINED SPECIFICATION

Same effect as above As f2 does not have a Spec, s3 gets the value None instead of Some[String] Extract value or default: Get the value if it exists. Extract value or default: If the value does not exist, a default value is given.

val s4 = m / Feature("f1") !! Gist val s5 = m / Feature("f2") !! Spec

Extracting sets of concepts from models


var m = Model( Feature("f1") has Spec("A"), Feature("f2") has Spec("B"), Feature("f1") owns ( Feature("f2"), Feature("f3") ), Product("p1") requires ( Feature("f1"), Feature("f2") ), Feature("f4") has Gist("C") )

Models can be constructed by applying sequences of entities linked to one or many nodes via either has or some relation, such as owns, requires, excludes, etc. (See further the reqT type structure.) The nodes (entities, attributes) and relations can be extracted using various operations on models explained below.

m.sources m.destinations m.entities m.undefined m.attributes m.relationSources m.attributeSources m.unrelated m.unsourced m.parents m.children m.roots

f1,f2,p1,f4 f1,f2,f3 f1,f2,f3,p1,f4 f3 A,B,C f1,p1 f1,f2,f4 f4 p1,f4 f1 f2,f3 f1

Set of all entities that are sources of links in model m. Set of all entities that are destinations of relations in model m. Set of all entities. Same as: m.sources ++ m.destinations Set of all entities that are destinations and not sources. Same as: Set of all attributes of all entities of model m. m \ has sources m / has sources m.entities diff m.relationSources diff m.destinations (m.relationSources ++ m.unrelated) diff m.destinations m / owns sources m / owns destinations m.parents diff m.children
for (e <- m.destinations; if (!m.sources.contains(e))) yield e

Some predicates defined in class Model


def isSource(e: Entity): Boolean = sources.contains(e) def isDestination(e: Entity): Boolean = destinations.contains(e) def isUndefined(e: Entity): Boolean = undefined.contains(e) def isDefined(e: Entity): Boolean = !isUndefined(e) def hasAttribute[T](a: Attribute[T]):Boolean = attributes.contains(a) def isRoot(e: Entity): Boolean = roots.contains(e) def isParent(e: Entity): Boolean = parents.contains(e) def isChild(e: Entity): Boolean = children.contains(e)

Import and export models to strings and files


var m = Model(Feature("f") has Spec("s")) m.toTable m.toTable(";", false) m.toScala m.toTable.save("mymodel.txt") m.toScala.save("mymodel.scala") m.toScala.save("C:/Users/xx/mymodel.scala") val s = Model.fromTable("mymodel.txt") s.save("mymodel.scala") :load mymodel.scala interpret("var m = " + s) m.toHtml m.toHtml.save("mymodel.html") val myDocTempl = DocumentTemplate("Title", Text("Intro para1", "Intro para2"), Chapter("Chap 1", Text("the model"), m => m ) ) m.toHtml(myDocTempl) Create a new model. Gives a string in tab-separated table format. Gives a table separated with ; and with no heading row. Gives a string with the Scala code that generates the model. Save the table string to a file. Save the Scala code that generates the model. Specify an absolute path where to save the file. Load a model into a String from a tab-separated text file. Save the loaded string as a model that can be interpreted. Interpret a scala file in the Scala REPL. Use last resX val. In Kojo: interpret a String s containing a model. Generate HTML code using the default document template Save it to a file. Create a minimal document template.

Use myDocTempl as document template for HTML generation

You might also like