Showing posts with label quality. Show all posts
Showing posts with label quality. Show all posts

Tuesday, July 23, 2013

Web: Faulty HTML, JS, and CSS code, hurts your page Performance, Quality and Debugging.

HTML page is the core

Yes, it is the core of every web project. Therefore, it is very important to code your HTML page properly since it forms the foundation for everything else. Because it is the core of every web page, so without a solid foundation, the stuff you build upon it will easily break.

All web browsers are very forgiving and will often render a page correctly even if the HTML is slightly faulty, and your page finally will render, but you should get your attention for such behavior. I do, however, recommend that you make sure the HTML is coded properly, for a number of reasons:

  • Performance
    Correct HTML code renders faster than incorrect HTML.

    How it comes? Okay let us see, if your code done properly, the browser will interpret the HTML in strict mode, in which it assumes that you know what you are doing. Incorrectly done, and it will switch to quirks mode, in which it is a lot more forgiving in its interpretation of the code.

    This means that you can get away with sloppy code, but since the browser has to guess what you mean, the page takes longer to render.

  • Quality
    Naturally, you want to look professional, and you just don’t look good with HTML that doesn’t validate. Invalid code is the sign of a developer who doesn’t know what he’s doing.

  • Debugging

    In addition, if you don’t have the HTML right, strange errors may occur in your CSS or JavaScript that are really hard to find.

    Both the CSS and a lot of the JavaScript code relies on the HTML being correct, so to make it easier for yourself, make sure that your HTML is correct by validating it frequently.

    This will save you a lot of time and grief.

How do you know that you have a correct HTML code?

It is a simple answer, fortunately W3C (World Wide Web Consortium) provides a tool which validate your code, whether it is a live page by providing its URL, or resides on your computer by uploading the file or past the code.

You will find this validator at W3C markup validation service.

Also your browsers are bundled with validation and inspection tools such as developer tools, alongside a bunch of extensions you can add to your browser for validation process.

Some of Firefox browser tools:

  1. Page Validator: https://addons.mozilla.org/en-US/firefox/addon/2250
  2. Html Validator: https://addons.mozilla.org/en-US/firefox/addon/249
  3. Web Developer Toolbar: https://addons.mozilla.org/en-US/firefox/addon/60

With these tools at your disposal, you are more than ready to get started.


Saturday, April 21, 2012

Architecture: Modeling & Designing Software Projects Architecture

When I model and design the architecture of software project, first thing I consider is what is the software project type?

My experience in this field of projects architecture has taught me that most applications fails into seven software types, each type has its own technology's, communication patterns, architectural patterns and design steps.

The software categories are:

1. Object oriented Software:
The object-oriented design uses the concepts of information hiding, classes, and inheritance. This results in the design of a sequential object-oriented software architecture, which would be implemented as a sequential program with one thread of control.
2. Client / Server Software.
In these systems, a client is a requester of services and a server is a provider of services. Typical servers are file servers, database servers, and line printer servers. Client/server architectures are based on client/service architectural patterns, the simplest of which consists of one service and multiple clients. This pattern has several variations, which will be described next. In addition, certain decisions need to be considered about the design of client/server architectures, such as whether the server should be designed as a sequential or concurrent subsystem, what architectural structure patterns to use for the design of the client/server architecture, and what architectural communication patterns to use for interaction between the clients and the services.

Also differentiates between a server and a service. A server is a hardware/ software system that provides one or more services for multiple clients. A service in a client/server system is an application software component that fulfills the needs of multiple clients. Because services execute on servers, there is sometimes confusion between the two terms, and the two terms are sometimes used interchangeably. Sometimes, a server will support just one service or perhaps more than one; on the other hand, a large service might span more than one server node. In client/server systems, the service executes on a fixed server node(s) and the client has a fixed connection to the server.
3. Service-Oriented Architecture.
SOA is a distributed software architecture that consists of multiple autonomous services. The services are distributed such that they can execute on different nodes with different service providers. With a SOA, the goal is to develop software applications that are composed of distributed services, such that individual services can execute on different platforms and be implemented in different languages. Standard protocols are provided to allow services to communicate with each other and to exchange information. In order to allow applications to discover and communicate with services, each service has a service description; the service description defines the name of the service, the location of the service, and its data exchange requirements.

A service provider supports services used by multiple clients. Usually, a client will sign up for a service provided by a service provider, such as an Internet, email, or Voice over Internet Protocol (VoIP) service. Unlike client/server architectures, in which a client communicates with a specific service provided on a fixed server configuration, this chapter describes SOAs, which build on the concept of loosely coupled services that can be discovered and linked to by clients (also referred to as service consumers or service requesters) with the assistance of service brokers. This document describes how to design SOAs, how to design services, and how to reuse services.
4. Distributed Component-Based Software.
In the design of software architectures for a distributed component-based software design; the component-based software architecture for the distributed application is developed. The software application is structured into components, and the interfaces between the components are defined. To assist with this process, guidelines are provided for determining the components. Components are designed to be configurable so that each component instance can be deployed to a different node in a geographically distributed environment.

Components are initially designed using the subsystem structuring criteria. Additional component configuration criteria are used to ensure that components are indeed configurable – in other words, that they can be effectively deployed to distributed physical nodes in a distributed environment.
5. Concurrent Real-Time Software.
The real-time software is a concurrent architecture usually, having to deal with multiple streams of input events. They are typically state-dependent, with either centralized or decentralized control.

Real-time software architectures are concurrent architectures that usually have to deal with multiple streams of input events. They are typically state-dependent, with either centralized or decentralized control. Thus, the design of finite state machines, state-dependent interaction modeling, and the control patterns, are very important in the design of real-time software architectures.
6. Software Product Line.
It is architectures for families of products that need to capture both the commonality and variability in the family.

A software product line (SPL) consists of a family of software systems that have some common functionality and some variable. Software product line engineering involves developing the requirements, architecture, and component implementations for a family of systems, from which products (family members) are derived and configured.

The problems of developing individual software systems are scaled upwards when developing SPLs because of the increased complexity due to variability management.

As with single systems, a better understanding of a SPL can be obtained by considering the multiple views, such as requirements models, static models, and dynamic models of the product line. A graphical modeling language such as UML helps in developing, understanding, and communicating the different views. A key view in the multiple views of a SPL is the feature modeling view. The feature model is crucial for managing variability and product derivation because it describes the product line requirements in terms of commonality and variability, and defines the product line dependencies. Furthermore, it is desirable to have a development approach that promotes software evolution, such that original development and subsequent maintenance are both treated using feature-driven evolution.
7. Framework Software.
A software framework is an abstraction in which software providing generic functionality can be selectively changed by user code, thus providing application specific software. It is a collection of software libraries providing a defined application programming interface (API). It is a universal, reusable software platform used to develop applications, products and solutions.

Software Frameworks include support programs, compilers, code libraries, an application programming interface (API) and tool sets that bring together all the different components to enable development of a project or solution.

Frameworks contain key distinguishing features that separate them from normal libraries:

7.1. Inversion of control - In a framework, unlike in libraries or normal user applications, the overall program's flow of control is not dictated by the caller, but by the framework.

7.2. Default behavior - A framework has a default behavior. This default behavior must actually be some useful behavior and not a series of no-ops.

7.3. Extensibility - A framework can be extended by the user usually by selective overriding or specialized by user code providing specific functionality.

7.4. Non-modifiable framework code - The framework code, in general, is not allowed to be modified. Users can extend the framework, but not modify its code.
-----------------------------------------------------------------------
Last thing is very important should be considered when architecting any project. It is Non-Functional requirements and should be taken into consideration when designing such software types from the modeling and design stage not when implementing the project.

In my architecture document I called it Software quality attributes.

Software quality attributes:
Refer to the nonfunctional requirements of software, which can have a profound effect on the quality of a software product. Many of these attributes can be addressed and evaluated at the time the software architecture is developed. Software quality attributes include maintainability, modifiability, testability, traceability, scalability, reusability, performance, availability, and security.

Some software quality attributes are also system quality attributes because they need both the hardware and software to achieve high quality. Examples of these quality attributes are performance, availability, and security. Other software quality attributes are purely software in nature because they rely entirely on the quality of the software. Examples of these quality attributes are maintainability, modifiability, testability, and traceability.


Saturday, February 11, 2012

Test: JUnit 4 Do's and Don'ts (An important notes)

DEFINITION:

A unit test examines the behavior of a distinct unit of work. Within a Java application, the “distinct unit of work” is often (but not always) a single method. By contrast, integration tests and acceptance tests examine how various components interact. A unit of work is a task that isn’t directly dependent on the completion of any other task.
A JUnit 4 test case class skeleton:

1.Do not name your test main class Test.java;
Which has the same short name as @Test annotation. Unless you explicitly use @org.junit.Test, @Test will resolve to your test class, instead of org.junit.Test annotation type.

2.Avoid using Java assertion;
Use static assertXXX methods (statically imported) in org.junit.Assert class. Java assert is turned off by default, and can be enabled only at command line with "java -ea", or "java -enableassertions" options. So some tests using Java assert will always pass when running with the default configuration, regardless of the actual test conditions. For example, the following method passes unless -ea option is passed to java:


A secondary reason to favor org.junit.Assert.assertXXX over Java assert is, the former is a richer API with more descriptive output, whereas Java assert, in its common form, only fails with java.lang.AssertionError and stack trace with no description. Java assert can also provide details with a second param: assert false : reason.

Maven surefire plugin automatically enables Java assertions when running JUnit tests on JDK 1.4 and above. So when running with surefire, there is no problem of false positive test results. But still I would like my JUnit tests to work the same way across all testing environment.

3.Avoid using assertTrue(list1.equals(list2));
Use assertEquals(list1, list2) instead. assertTrue will only print out the useless message like "expecting true, but actual false", whereas assertEquals gives more helpful message like "expected:[null, 1, 2], but was:[1, 2]"

4.Do not add assertTrue(true) at the end of a @Test
To signal the success result. It's just not needed. The test simply passes when nothing goes wrong.

5.@Test method can declare throws clause;
e.g., throws NamingException. When an exception is thrown during test run, the test is failed. So use exception as a means to communicate test failures. Do not try-catch an exception, just to print it and manually fail() it. For example, do this:

Do NOT do this:

When running the try-catch version, ArithmeticException stack trace is printed, followed by another stack trace of java.lang.AssertionError from calling fail(), whereas in the shorter version, only the ArithmeticException is logged and hence much easier to trace.

6.How to run a single test?
org.junit.runner.JUnitCore, the default command-line runner, takes a list of test classes as input, but doesn't support running a single test method. Other tools and IDE may support it by providing their own runner. With maven surefire 2.7.3+ and JUnit 4 tests, it is supported with a -D sysprop (link):

It is preferable to put the test name at the very end of the line so it's easier to go through the history and edit command.

7.To check the version of your JUnit:

8.To skip or exclude a test;
Use @Ignore (org.junit.Ignore).

9.To test a performance;
Use @Test(timeout = xx) (org.junit.Test) specify timeout in milliseconds to cause a test method to fail if it takes longer than that number of milliseconds.
For example: if you test a database query and it should take by max 1 second run this query inside a test case with timeout of 1000 ms, and tweak it further to reach this goal.

10.To test throwing a certain exception;
Use @Test(expected = xx) (org.junit.Test) where xx is a Throwable or sub of it, to cause a test method to succeed if an exception of the specified class is thrown by the method.

11.To test suite of test classes;
Use @RunWith(Suite.class) (org.junit.runner.RunWith) and @Suite.SuiteClasses( { ATest.class, A1Test.class }) (org.junit.runners.Suite) on class level as suite class that runs multiple test classes at the same time, in order they specified in the SuiteClasses, so ATest class test cases will run first before A1Test test cases.

The test suite could be empty and just for groping related test classes.

12.To test suite of suites;
Use 
@RunWith(Suite.class) (org.junit.runner.RunWith) and  @Suite.SuiteClasses( { ATestSuite.class, BTestSuite.class })(org.junit.runners.Suite) on class level as suite master class that runs multiple suite classes at the same time, in order they specified in the SuiteClasses, so ATestSuite class test cases for all classes it includes will run first before BTestSuite test cases.

The test suite could be empty and just for groping related test classes.

13.Running parameterized tests;
Use @RunWith(value = Parameterized.class) (org.junit.runner.RunWith) and @Parameters(org.junit.runners.Parameterized.Parameters) on a class method with signature "public static Collection name(){}" contains array of test parameters.

The Parameterized test runner allows you to run a test many times with different sets of parameters. Test class should have a constructor with argument list parameters equals to parameterized method array value.

When running a parameterized test class, instances are created for the cross-product of the test methods and the test data elements. Each instance of test class will be constructed using the n-argument constructor and the data values in the @Parameters method.

As the following example:

This test class will run and resulting with three test cases to run as testAdd[0], testAdd[1], testAdd[2].

Other testing types is shell and mock testing.

References:
1- JUnit in Action 2nd edition by (Petar Tahchiev,Felipe Leme,Vincent Massol,Gary Gregory).
2- Java how to Junit notes.

Monday, March 28, 2011

SE: Principles of Quality Software Development

Quality Software Development Principles


So, you have figured out how to build your applications, and they work just like the ones from which you learned. You are getting paid to write these applications, so you are now a professional developer. But how do you know if you are doing a good job?

There are literally thousands upon thousands of articles debating the measures of quality software with each of them offering you their own solution for how you should answer this question.

This body of work can be boiled down to a few questions:

Does the software do what it is supposed to do?
Of course, this is a loaded question. It is entirely possible to say that a piece of software does what it is supposed to do (as defined by a requirements specification), but this is absolutely worthless. In essence, you are talking about a failure of your requirements gathering process, which leads you to build the wrong thing. Your software is being built to serve a particular need, and if it does not satisfy that need (for whatever reason), the software is a failure.

Does the software do things it shouldn’t do?
Developers like to refer to this phenomenon as undocumented features, but your users will refer to them as bugs. Everyone prefers to build bug-free software, but in the real world, this just doesn't happen. All men may be created equal, but all bugs are not. Bugs that do not impact the functioning of the system -or the business process they support -are obviously far less important than those that do.

Did you deliver the software in a timely manner?
Timing is everything, and this is true nowhere more than in software in which the pace of change is incredible. If your software takes so long to deliver that it is no longer appropriate to the business process it supports, then it is worthless. The great untold secret behind the high percentage of software projects that end in failure is that many of them simply could not keep up with the pace of technological innovation and died trying.

Could you do it again if you had to?
Of course, you will have to! This is the job---writing and delivering software that complies with the preceding questions. The key here is that you should not have to learn all of your hard knocks lessons every time you build software. You will invariably be asked to deliver your software again with fixes and enhancements, and you hopefully do not have to fix the same bugs over and over again nor have the same integration challenges repeatedly. “At least we don’t have to deal with this next time” should be a truth that comforts you in your integration and bug fixing, and not a punch line to a development team joke.

These questions may seem like common sense---because they are! But there is an old saying that “common sense is neither,” so it is important not to assume that everyone is on the same sheet of music. Furthermore, the U.S. Army Rangers have a saying, “Never violate any principles, and do not get wrapped up in technique.”

You will find this a helpful maxim in dealing with the maze of processes, products, and techniques involved in software development. These are the core principles of software development, and how you get there is technique. Do not lose sight of the distinction between these two things.