CSC/ECE 517 Fall 2009/wiki3 15 assertions: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
mNo edit summary
mNo edit summary
Line 113: Line 113:


* they remove the need for ''passive assertions'' (in the form of comments) and instead actively assert the condition and fail if false during run-time: comments may outlive the code and may not hold for the new code. They act like passive assertions, so its the programmer who has to take care of the condition. In case of ''assert'' statements, they enforce the conditions and never outlive the code. If the code changes, the assert statement has to change too, for the program to execute. They thus act as ''active'' snippets of comments.
* they remove the need for ''passive assertions'' (in the form of comments) and instead actively assert the condition and fail if false during run-time: comments may outlive the code and may not hold for the new code. They act like passive assertions, so its the programmer who has to take care of the condition. In case of ''assert'' statements, they enforce the conditions and never outlive the code. If the code changes, the assert statement has to change too, for the program to execute. They thus act as ''active'' snippets of comments.


* they make you more confident of your code: The programmer makes a certain assumptions during the coding phase. Assertions validate the programmer's assumptions. If any of them turns out to be false, code without assertions may execute and show unexpected behavior. ''Assertions'' avoid such situations and make the code less buggy.
* they make you more confident of your code: The programmer makes a certain assumptions during the coding phase. Assertions validate the programmer's assumptions. If any of them turns out to be false, code without assertions may execute and show unexpected behavior. ''Assertions'' avoid such situations and make the code less buggy.


* they help refactor the code: Whenever somebody's refactoring the code, leaving the assertions in place (or modifying them accordingly) ensures that the logic is not flawed and the refactor was actually done (without altering the logic). It is a way to validate the process of refactoring. The same hold true for optimization. Assertions ensure that while in the process, the program logic was not altered.
* they help refactor the code: Whenever somebody's refactoring the code, leaving the assertions in place (or modifying them accordingly) ensures that the logic is not flawed and the refactor was actually done (without altering the logic). It is a way to validate the process of refactoring. The same hold true for optimization. Assertions ensure that while in the process, the program logic was not altered.


*  they act as embedded tests: A very good example is the development of Program 1: MeToo. A lot of assertions were used in the unit tests. Assertions are like small tests embedded within the code. They simplify the testing of the code.
*  they act as embedded tests: A very good example is the development of Program 1: MeToo. A lot of assertions were used in the unit tests. Assertions are like small tests embedded within the code. They simplify the testing of the code.


*  
 
* they help in debugging: When a program has assertions, it is easy to narrow down the error since the programmer now knows that if there is an assertion error then the problem must be somewhere in the vicinity of the assertion. They thus help in efficient debugging.


== References ==
== References ==

Revision as of 01:04, 11 November 2009

Programming with assertions

Assertions are predicates or statements with expressions which the programmer thinks should be true at the time of execution. Assertions are a powerful way of detecting bugs in programs.

Overview

Every software product goes though a Software Process or more commonly known as Software Development Cycle. The various stages in the cycle are:

Waterfall model of Software Development Cycle. Image courtesy: Pressman, Roger S. Software Engineering: A Practitioner's Approach", 2001 Fifth Ed.
  • Planning
  • Design
  • Development
  • Testing
  • Release and Maintenance

It is impossible for a programmer to make any program a hundred percent bug free. Even worse, there maybe subtle things which the programmer assumes are always true but may not be so in many corner cases. Debugging is an integral part of the Software Process. Bugs can crop up anytime due to various test cases formulated all through these aforementioned stages. To be sure that whatever the programmer assumes is true, assertions can be set up in the program. If ever, the condition evaluates to be false, the program terminates with an assertion. Another way to put it is that assertions are a way to show the programmer that things cannot be taken for granted by the latter. Assertions can be thought of as medium of validating the correctness of modules.

Purpose

The various uses of assertions are:

  • Validates correctness of (sub)program
  • Supports programming by contract (documentation)
  • Helps in debugging
  • Exception handling by integrating assertion failures to be detected dynamically

Assertions can be used by the programmer to make sure that wrong runtime assumptions (by the programmer) can be caught.

Types of assertions

Assertions can be categorized primarily as follows:

  • Pre-conditions
  • Post-conditions
  • Class invariants
  • Invariants (Control-flow, Loop etc.)
  • Loop variants

As Dr.Gehringer mentions, the first three classes are discussed in class and will not be a focus of this wiki. Instead, this will concentrate on the other types of assertions, viz., Control flow, Loop invariants and Loop variants. Invariants are those conditions with a precondition as well as post condition. A loop invariant is an expression for a variable which remains constant through-out the loop. On the other hand, control-flow invariants are those cases which specify that the control should never reach to that part of code. Consider the following code:

for (....) {

  if (...)
      return x;
  else if (...)
      return y;
 
 /* Control should never reach here */

}

Now observe how control-flow invariance can be validated by assertions:

for (....) {

  if (...)
      return x;
  else if (...)
      return y;
 
  assert false

}

They are also a very useful tool to detect logical errors. For e.g consider the following code:

switch(scase) {

  case 1: ....
  case 2: ....
  default: assert false;

}

This code fragment clearly says that the programmer assumes that the variable scase will take either of the listed values. If the variables reaches the default segment, then there is a logical error in the program.

Numerous other run-time checks can be made. The following example illustrates that:

if (threads % 4 == 0) {....}

else if (threads % 4 == 1) {....}

else if (threads % 4 == 2) {....}

else {

  // we know that it has to be 3
  assert(threads % 4 == 3);
  ....

}

This method is called as asserting an Internal invariant. The latter means that even though its obvious that the result would be 3, we eliminate any logical errors by asserting that.

Programming languages supporting native assertions

The following programming languages support assertions natively:

  • Cobra
  • D
  • Eiffel
  • Fortress
  • Lisaac
  • Nice
  • Oxygene (formerly Chrome)
  • Sather
  • SPARK, via static analysis of Ada programs
  • Spec#

Advantages and disadvantages of assertions

Some programming languages natively support assertions (mentioned above) while some support through add-ins (like C/C++, C#, Java, Javascript etc.). However, most of the above listed languages are high level languages with less popularity. Hence the need for supporting assertions in the commonly used languages is important.

There are many advantages of assertions. Some of them are enumerated here:

  • they remove the need for passive assertions (in the form of comments) and instead actively assert the condition and fail if false during run-time: comments may outlive the code and may not hold for the new code. They act like passive assertions, so its the programmer who has to take care of the condition. In case of assert statements, they enforce the conditions and never outlive the code. If the code changes, the assert statement has to change too, for the program to execute. They thus act as active snippets of comments.


  • they make you more confident of your code: The programmer makes a certain assumptions during the coding phase. Assertions validate the programmer's assumptions. If any of them turns out to be false, code without assertions may execute and show unexpected behavior. Assertions avoid such situations and make the code less buggy.


  • they help refactor the code: Whenever somebody's refactoring the code, leaving the assertions in place (or modifying them accordingly) ensures that the logic is not flawed and the refactor was actually done (without altering the logic). It is a way to validate the process of refactoring. The same hold true for optimization. Assertions ensure that while in the process, the program logic was not altered.


  • they act as embedded tests: A very good example is the development of Program 1: MeToo. A lot of assertions were used in the unit tests. Assertions are like small tests embedded within the code. They simplify the testing of the code.


  • they help in debugging: When a program has assertions, it is easy to narrow down the error since the programmer now knows that if there is an assertion error then the problem must be somewhere in the vicinity of the assertion. They thus help in efficient debugging.

References

  1. R. S. Pressman. Software Engineering "A Practitioner Approach" New York McGraw-Hill, 2001, p386-p429.
  2. http://en.wikipedia.org/wiki/Waterfall_model
  3. http://en.wikipedia.org/wiki/Spiral_model
  4. http://www.testinggeek.com/index.php/testing-types/life-cycle/55-bigbang-integration-testing
  5. http://www.cs.umd.edu/~aporter/html/currTesting.html
  6. https://wiki.cac.washington.edu/display/SWTest/Functional+Testing
  7. http://www.devbistro.com/articles/Testing/Requirements-Based-Functional-Testing
  8. http://www.bugzilla.org/
  9. https://launchpad.net/
  10. http://docs.joomla.org/Functional_Testing
  11. http://www.opensourcetesting.org/