CITS5501 lab 5 (week 6) – logic-based testing

0. Notation

When writing logic expressions, we will often use mathematical notation for “and”, “or”, and “not”:

This notation is independent of any language; it could be turned into Java, or C, or Python – each of which uses different logical operators – depending on what language our system and our tests are implemented in.

If writing actual Java code, however, we use the normal Java logical operators:

Other operators and languages

Java also has non–short-circuiting logic operators, | and &.

We won’t be using any Python in this unit – but for reference, in Python, the logic operators are all spelled out as English words: “and”, “or” and “not”.

1. Terminology – clauses and predicates

If you need to, review the lecture material and recommended readings that explain what predicates and clauses are.

What are the clauses in the predicates below?

  1. \(((f \leqslant g) \wedge (x > 0)) \vee (M \wedge (e < d +c))\)

  2. \(G \vee ((m > a) \vee (s \leqslant o + n)) \wedge U\)

2. Making clauses active

To make a particular clause \(c\) in some predicate active means to assign values to variables so that the truth-value of the whole predicate depends on \(c\).

When coming up with test values which make clauses active, the easiest way of showing your test values is in a table.

E.g. Suppose we have a predicate \(s \wedge (m \vee w)\), where

If asked to come up with test inputs which make each clause active in turn, and achieve Restricted Active Clause Coverage, we could show them like this:

Test description Inputs Predicate value
Make s active, and
  s = true
  s = false
s = true, m = true, w = false
s = false, m = true, w = false
true
false
Make m active, and
  m = true
  m = false
s = true, m = true, w = false
s = true, m = false, w = false
true
false
Make w active, and
  w = true
  w = false
s = true, m = false, w = true
s = true, m = false, w = false
true
false

(Here, we aren’t told what the expected outcome is if the predicate comes out true or false; if we were, we could add a column “Expected outcome” which listed this.)

If you aren’t told the exact types of variables or methods used in a predicate, that means you should be able to work them out from context. For example, for the predicate

\[ (x > 0) \vee (M \wedge (e < d +c)) \]

you can assume that \(M\) is a boolean, and that \(x\), \(c\), \(d\) and \(e\) are some numeric type (such as int).

For each of the clauses in the predicates below, identify test inputs which will make the clause active (that is: state what values need to be assigned to the variables in the predicate), and vary that clause so it takes on both true and false values. (In other words: write test values that achieve Restricted Active Clause Coverage.) Explain your reasoning.

  1. \(A \vee (B \wedge \neg C)\)
  2. \(x > 0 \; \vee (M \wedge (e < d +c))\)
  3. \(G \vee (m \geqslant a) \vee H \wedge U\)

3. Scenario – trap-doors

Suppose a component under test has the following requirements:

If the lever is pulled and the chair is occupied, open the trap-door.

If the button is pressed, open the trap-door.

Represent the component as a set of logic expressions. You should explain what each variable in your expressions means. (For an example, look in section 2 at the way we gave definitions for the variables in the predicate \(s \wedge (m \vee w)\).)

(Hint: if you’re stuck, try writing out what the component does as one or more “if” statements, in pseudocode. Then recall that the set of all predicates in a system means the set of all logical expressions found in things like “if” statements.)

4. Scenario – login page

Suppose you are part of a team developing a website called “RateMyVeterinarian”, where people can log in and provide anonymous reviews of the veterinarian services they use.

Requirements for the site are currently being finalised, and one requirement is stated as follows:

When a user enters a user ID and password into the login page and hits the “log in” button, then if that user ID is listed in the “users” database, and the password matches against the password in the record for that user, and the user record does not state that the account has been disabled, a “Welcome” page should be displayed.

  1. How easy to understand do you think this requirement is? If you think it could be made easier to understand, suggest how.

  2. One of your colleagues suggests that because correctly authenticating users (and keeping their details secure) is an important feature, this requirement should be thoroughly tested – so you should design a test suite that meets RAC (Restricted Active Clause) levels of coverage. Do you agree? Why or why not?

4. Tips and tricks

When solving problems that involve logic-based testing, make sure you understand the difference between expressions and statements in the programming language or languages that you’re using.

For instance, simple Java if statements are of the form:

   if ( Expression ) { Statements }

Statements are parts of the language that do things; we usually execute them in order to achieve some side effect. Expressions evaluate to a Java boolean, and we typically intend that they should not have side effects – they just evaluate to true or false.

When we do logic-based testing, we’re focusing on the collection of logic expressions of a program or system that control program flow, and working out how to write tests that thoroughly exercise the component parts (the clauses) of those expressions.

Confusing expressions with statements, or vice versa, is a common reason for students to do poorly in test or exam questions involving logic-based testing.