Wednesday, September 18, 2024

Fundamentals of Software Testing


Originally posted on jan , 23 2009, Published again on Sept,18,2024

extracted completely from 

 

http://testingsoftware.blogspot.com/2005/11/fundamentals-of-software-testing.html

 


Objectives of Testing

Finding of Errors - Primary Goal
Trying to prove that software does not work. Thus, indirectly verifying that the software meets the requirements
Software Testing
Software testing is the process of testing the functionality and correctness of software by running it. Software testing is usually performed for one of two reasons:
(1) defect detection
(2) reliability or Process of executing a computer program and comparing the actual behavior with the expected behavior

What is the goal of Software Testing?
* Demonstrate That Faults Are Not Present
* Find Errors
* Ensure That All The Functionality Is Implemented
* Ensure The Customer Will Be Able To Get His Work Done

Modes of Testing
* Static Static Analysis doesn¡¦t involve actual program execution. The code is examined, it is tested without being executed Ex: - Reviews
* Dynamic In Dynamic, The code is executed. Ex:- Unit testing

Testing methods
* White box testing Use the control structure of the procedural design to derive test cases.
* Black box testing Derive sets of input conditions that will fully exercise the functional requirements for a program.
* Integration Assembling parts of a system

Verification and Validation
* Verification: Are we doing the job right? The set of activities that ensure that software correctly implements a specific function. (i.e. The process of determining whether or not products of a given phase of the software development cycle fulfill the requirements established during previous phase). Ex: - Technical reviews, quality & configuration audits, performance monitoring, simulation, feasibility study, documentation review, database review, algorithm analysis etc
* Validation: Are we doing the right job? The set of activities that ensure that the software that has been built is traceable to customer requirements.(An attempt to find errors by executing the program in a real environment ). Ex: - Unit testing, system testing and installation testing etc

What's a 'test case'?
A test case is a document that describes an input, action, or event and an expected response, to determine if a feature of an application is working correctly. A test case should contain particulars such as test case identifier, test case name, objective, test conditions/setup, input data requirements, steps, and expected results

What is a software error ?
A mismatch between the program and its specification is an error in the program if and only if the specifications exist and is correct.

Risk Driven Testing
What if there isn't enough time for thorough testing?
Use risk analysis to determine where testing should be focused. Since it's rarely possible to test every possible aspect of an application, every possible combination of events, every dependency, or everything that could go wrong, risk analysis is appropriate for most software development projects. This requires judgment skills, common sense, and experience.

Considerations can include:
- Which functionality is most important to the project's intended purpose?
- Which functionality is most visible to the user?
- Which aspects of the application are most important to the customer?
- Which parts of the code are most complex, and thus most subject to errors?
- What do the developers think are the highest-risk aspects of the application?
- What kinds of tests could easily cover multiple functionalities?
Whenever there's too much to do and not enough time to do it, we have to prioritize so that at least the most important things get done. So prioritization has received a lot of attention. The approach is called Risk Driven Testing. Here's how you do it: Take the pieces of your system, whatever you use - modules, functions, the section of the requirements - and rate each piece on two variables, Impact and Likelihood.


Risk has two components: Impact and Likelihood

Impact
is what would happen if this piece somehow malfunctioned. Would it destroy the customer database? Or would it just mean that the column headings in a report didn't quite line up?

Likelihood
is an estimate of how probable it is that this piece would fail. Together, Impact and Likelihood determine the Risk for the piece.


Test Planning

What is a test plan?
A software project test plan is a document that describes the objectives, scope, approach, and focus of a software testing effort. The process of preparing a test plan is a useful way to think through the efforts needed to validate the acceptability of a software product.

Elements of test planning
* Establish objectives for each test phase
* Establish schedules for each test activity
* Determine the availability of tools, resources
* Establish the standards and procedures to be used for planning and conducting the tests and reporting test results
* Set the criteria for test completion as well as for the success of each test

 

The Structured Approach to Testing

Test Planning
* Define what to test
* Identify Functions to be tested
* Test conditions
* Manual or Automated
* Prioritize to identify Most Important Tests
* Record Document References

Test Design
* Define how to test
* Identify Test Specifications
* Build detailed test scripts
* Quick Script generation
* Documents

Test Execution
* Define when to test
* Build test execution schedule
* Record test results


Bug Overview

What is a software error?
A mismatch between the program and its specification is an error in the Program if and only if the specification exists and is correct.
Example: -
* The date on the report title is wrong
* The system hangs if more than 20 users try to commit at the same time
* The user interface is not standard across programs

Categories of Software errors
* User Interface errors
* Functionality errors
* Performance errors
* Output errors
* documentation errors

What Do You Do When You Find a Bug?
IF A BUG IS FOUND,
* alert the developers that a bug exists
* show them how to reproduce the bug
* ensure that if the developer fixes the bug it is fixed correctly and the fix
* didn't break anything else
* keep management apprised of the outstanding bugs and correction trends

Bug Writing Tips
Ideally you should be able to write bug report clearly enough for a developer to reproduce and fix the problem, and another QA engineer to verify the fix without them having to go back to you, the author, for more information.
To write a fully effective report you must :-
* Explain how to reproduce the problem
* Analyze the error so you can describe it in a minimum number of steps
* Write a report that is complete and easy to understand


Product Test Phase - Product Testing Cycle

Pre-Alpha
Pre-Alpha is the test period during which QA, Information Development and other internal users make the product available for internal testing.
Alpha

Alpha is the test period during which the product is complete and usable in a test environment but not necessarily bug-free. It is the final chance to get verification from customers that the tradeoffs made in the final development stage are coherent.
Entry to Alpha
* All features complete/testable (no urgent bugs or QA blockers)
* High bugs on primary platforms fixed/verified
* 50% of medium bugs on primary platforms fixed/verified
* All features tested on primary platforms
* Alpha sites ready for install
* Final product feature set Determined

Beta
Beta is the test period during which the product should be of "FCS quality" (it is complete and usable in a production environment). The purpose of the Beta ship and test period is to test the company's ability to deliver and support the product (and not to test the product itself). Beta also serves as a chance to get a final "vote of confidence" from a few customers to help validate our own belief that the product is now ready for volume shipment to all customers.
Entry to Beta

* At least 50% positive response from Alpha sites
* All customer bugs addressed via patches/drops in Alpha
* All bugs fixed/verified
* Bug fixes regression tested
* Bug fix rate exceeds find rate consistently for two weeks
* Beta sites ready for install

GM (Golden Master)
GM is the test period during which the product should require minimal work, since everything was done prior to Beta. The only planned work should be to revise part numbers and version numbers, prepare documentation for final printing, and sanity testing of the final bits.
Entry to Golden Master

* Beta sites declare the product is ready to ship
* All customer bugs addressed via patches/drops in Beta
* All negative responses from sites tracked and evaluated
* Support declares the product is supportable/ready to ship
* Bug find rate is lower than fix rate and steadily decreasing

FCS (First Customer Ship)
FCS is the period that signifies entry into the final phase of a project. At this point, the product is considered wholly complete and ready for purchase and usage by the customers.
Entry to FCS

* Product tested for two weeks with no new urgent bugs
* Product team declares the product is ready to ship
 

================================

 

Friday, June 30, 2017

Getting Ref of the View Object referenced by the current Iterator binding for One iterator page without knowing the name of the iterator

Getting Ref of the View Object referenced by the current Iterator binding for One iterator page without knowing the name of the iterator

In a previous blog (Playing around with ADFdatacontrol),  it was shown that you can get the ApplicationModule object without having to know the name of the Data Control. i mean Instead of this line of code
AppModuleImpl appmodule = (AppModuleImpl)ADFUtils.getApplicationModuleForDataControl("AppModuleDataControl");

you could write the following
        DCBindingContainer binding =   (DCBindingContainer)ADFUtils.getBindingContainer();
        DCDataControl cDataControl = binding.getDataControl();
        ApplicationModule AM =cDataControl.getApplicationModule();


Now, and in order to be more generic in code writing, here is a code that will get you the View Object to which the iterator binding of a page is bound to.
This code will work for simple pages that contain one iterator binding because if there are two iterator bindings within the same page definition, you will need to specify which one you
want

// this piece of code will get all iterator bindings for the page and will check that there is only ONE iterator binding, this implementation is much faster than iterator through the iterator and count it
    
   ArrayList arr = binding.getAllIterBindingList();
        if (arr instanceof Collection) {
            int size = (arr).size();
            System.out.println(size);
            if (size != 1) {
                System.out.println("not single iterator ok");
  //  practically, should through an exception  
              }
          
       else
 {
//  once you are sure there is only one iterator, then you fetch the first iteratorbinding in the list

                DCIteratorBinding ItrBind = (DCIteratorBinding)arr.get(0);

// here you get the viewobject that the iterator references without its name

                ViewObject voData = ItrBind.getViewObject();
 //  just playing around with some method of the view object to test               
                Long range = voData.getEstimatedRowCount();
                System.out.println("Range :" + range.toString());
                System.out.println("VO name " + voData.getDefFullName());
            }
        }
      else {
            System.out.println("not a collection ");
        }


You can now create a method that shall return the ViewObject 

    public ViewObject  getCurrentIteratorVO () {
        DCBindingContainer binding = (DCBindingContainer)ADFUtils.getBindingContainer();
        ArrayList arr = binding.getAllIterBindingList();
        if (arr instanceof Collection) {
            int size = (arr).size();
            System.out.println(size);
            if (size != 1) {
                System.out.println("not single iterator ");
            // practically, should through an exception
            }
            else {
               DCIteratorBinding ItrBind = (DCIteratorBinding)arr.get(0);
               ViewObject voData = ItrBind.getViewObject();
              return voData;
                 }
           } 
         else 
          {
            System.out.println("not a collection ");
         }
                return null;
    }

Call the method
    public String cb6_action() {
        // Add event code here...
        ViewObject vv = getCurrentIteratorVO();
        return null;
    }

The output is

1
Range :14


VO name model.EmpView

Tuesday, June 27, 2017

Playing around with ADF dataControl

While trying to figure out what one of our ex-colleagues at REALSOFT is programming a business rule engine admin screen for the Health Insurance Administration card issuance and administration software solution, i noticed the following piece of code

    AppModuleImpl appmodule =
        (AppModuleImpl)ADFUtils.getApplicationModuleForDataControl("AppModuleDataControl");

this piece of code is specific for the Oracle Application Development Framework that we use to build JEE web scalable , mission critical applications.

Being a principal in the company, i try to find ways not only to optimize the coding endeavor , but also to minimize costs. 

One way of doing that is obviously  by building reusable libraries, encapsulate the nitty-gritty issues and minimizing the things that the developer needs to understand about the framework in order to getting his applications up and running.

What i do not like about the above is that fact that the developer needs to know the Data Control  Name in order to access the ApplicationModule object 

 What i have in mind is to create a method that will get does not need the developer to know more that the method name in order to get the application module.  I fiddled around with helper classes found the following


public class Ammar {
    public Ammar() {
        super();
    }
    public void PlayWithDataControl(){
        DCBindingContainer binding =   (DCBindingContainer)ADFUtils.getBindingContainer();
        DCDataControl cDataControl = binding.getDataControl();
        ApplicationModule AM =cDataControl.getApplicationModule();
//        System.out.println(cDataControl.getName());  to make sure i am within the same data control
// another legitimate question is what if i have more that one page in the application, am i getting the application module pertaining to the page definition i am on?  well , the test below indicates that the answer is yes,, i created two pages, and called the following code from both, and each printed its own page definition name

System.out.println(    binding.getDef().getContainerName());
      
    }

So ,  i would just modify the above and add it to company Library

    public ApplicationModule getRSMyAppMod(){
        DCBindingContainer binding =  (DCBindingContainer)ADFUtils.getBindingContainer();
        return binding.getDataControl().getApplicationModule();
    }

you can then call it from your view controller ,, something like this, i am using strongly typed implementation here

    public String cb6_action() {
        // Add event code here...
        AppModuleImpl appMod = (AppModuleImpl)getRSMyAppMod();
        ViewObject vo = appMod.getEmpView1();
        ViewObjectImpl empView1 = appMod.getEmpView1();
}

Another corollary of the Binding container which i liked is the fact that i can fetch all the binding attributes

        List attrBindings = binding.getAttributeBindings();
        Iterator itr = attrBindings.iterator();
        while (itr.hasNext()){
            AttributeBinding attrBinding = (AttributeBinding)itr.next();
            String val = attrBinding.getInputValue().toString();
            System.out.println(val);

Yes another corollary is that one can find the  value of an attribute from the binding container directly by using the method    attrBinding.getName();


also i found in the ADFUtils helper method the following which return the value of any bound attribute..  This is very nice, and will make the life of people coming from forms background easier.
Just call the method ScreenValue instead of the getBoundAttribute, and it will be all fun


    public static Object getBoundAttributeValue(String attributeName) {
        return findControlBinding(attributeName).getInputValue();

Ammar  Sajdi  Third day of Eid at office enjoying the heat wave 35C

Sunday, June 25, 2017

Say Hi to Julia

By Ammar Sajdi

Well, Do not get too excited, Julia is a programming language. It saw the light on Valentine’s Day, 2012.
While it can be an effective general-purpose programming language, the real strength of Julia is the fact that provides for high-performance, parallel, and distributed computing.  


Well parallel and distributed caught my attention, I never wrote a program that can unleash the power of parallel computing. I looked at the language, and it is really easy to do parallel computing. This makes it suitable for applications that involve intense numerical analysis

if you want to know what people think of Julia refer to 

https://www.quora.com/What-is-your-take-on-Julia-language

someone said

There was never a doubt in my mind that Julia is good, probably the best language for the future, will succeed/already has for the scientific audience (as clearly better than all alternatives, for performance work where you also want to be "dynamic"). It's estimated to have exponential growth of users, doubling every 9 months now, estimated at 100,000 users, with I forget how many downloads per day. Look it up (it's in a video on YouTube, from one of the key Julia people).

I'm sure the rest of (non-HPC) programmers will eventually clue up, and use it as the general language that it is.

https://www.quora.com/Is-Julia-programming-language-growing-fast

finally, I met a young relative of mine who is studying Engineering at Stanford, and part of the industrial engineering curriculum is to take a course in Julia programming.

EDIT Sept 18, 2024:  So far it seems that Julia's programming language is not picking up as I thought. People still prefer to use Python. Julia could still be needed in certain situations like distributed and parallel processing.

https://www.reddit.com/r/Julia/comments/18s0ubz/is_julia_programming_language_destined_to_fade/

rgds

Ammar  Sajdi -  REALSOFT

ليش اسمه عيد

Ammar Sajdi   ,  2017

well I wrote about it before

3id in Arabic comes from E3adah (return, repetition). Saying Happy Eid implicitly means that one wishes the happy return of this occasion


Do I wish the return of events that occurred this year, well in the regional front, it has been bad and getting worse

civil war in Syria (not anymore a civil war, but a war fought by many countries on Syrian soil).

The Saudi war against Yemen,, Cholera breakout in Yemen, Gulf-Qatar Crises, Political unrest in Libya, Palestinian Hunger strike in Israeli prisons, and the list goes on.


Almotanabi summed it up by saying


عيد الي حال عدت يا عيد                                       بما مضى ام بامر فيك تجديد                         



ولا ماني شايف تجديد    شايف بما مضى بس اسوأ حالا


ولكن وعلى كل حال   كل عام ونتم بخير

Ammar

Thursday, May 11, 2017

The most captivating communicator in the history of Science Richard Feynman birthday is today

Richard Feynman, the most amusing, most captivating brilliant man  (In my opinion) would be 99 years.

Learn more about him and watch this video, watch his presentation skills, and his influential lecturing capabilities, he was always the center of attention.  watch and learn how to become a charming person

https://www.youtube.com/watch?v=LyqleIxXTpw

Ammar Sajdi
Amman, jordan 2017, May 11

Wednesday, May 10, 2017

Fuchsia

wondering what Fuchsia is?
mmm,
well it is a new product from Google!!  
You would guess most probably it is a piece of software, well you have got it right!
Rumor has it that it  Googles mysterious new OS. It is probably intended to power future google based devices like smartphones and tablets, and it will replace Android;
It has a new user interface called Armadillo, it is a new UI vastly different from anything you ve seen.  No icons, no gadgets, there are sneak previews floating around over the internet, go and find out

Ammar Sajdi

Sunday, May 07, 2017

<أَفَلَا يَتَدَبَّرُونَ الْقُرْآَنَ أَمْ عَلَى قُلُوبٍ أَقْفَالُهَا>

أَفَلَا يَتَدَبَّرُونَ الْقُرْآَنَ أَمْ عَلَى قُلُوبٍ أَقْفَالُهَا 

لا تقفل على قلبك

"كلما ازددت علما ازداد علمي بجهلي"

Monday, May 01, 2017

Crazy vacation - part I

P A R T (I)

I have not been blogging for quite a while about my activities for several reasons, however, I have decided to blog in order to document a vacation I took in Turkey.

It reminded me of earlier blogs that I had written ten years back when I visited Turkey with family. It was nice to go back and read what I wrote and then

I am reciting from that earlier block as it seems that some commonalities still exist.  The following tells you how the earlier blog began (http://oraclejo.blogspot.com/2007/08/untitled.html)


  • maybe it is LIS (Lack of Interest Syndrome) or my every-once-in-a-while mood swing cycle. Not being in the mood. As a remedial, I am taking a break, Yeah, I am traveling! What is unique this time is the fact that I shall be traveling on vacation with family and relatives.
well, this time i already traveled and I am back, I traveled on a sailing trip to the southern coast of Turkey with five guys namely 
  • Zaher Bushnaq
  • Rajai Bushnaq
  • AlaEddin Busnaq
  • Husam Katkhoda (Bushnaq)
The name Bushnaq comes from Bosnia because this family came from Bosnia early days of the last century.

The target (without a plan )set forth by Captain Rajai Bushanq was to sail from Marmaris to Bodrum and back in 5 days and 4 nights. Well, to cut your suspense short, i will tell you right away that it did not happen. Nothing happens without a good plan.  It is more than 400 Km round trip. In navigation, nautical miles unit of measure is used. A nautical mile is equal to 1850 Meters and hence it is longer than 1 Mile.  To add a piece of information, sailors, Pilots, and navigators in general use nautical miles, because a nautical mile is a measure that is based on the circumference of the earth and is equal to one minute of latitude. Note on the map that one sails very close to the Greek waters and you do not want to slip into their territories by mistake; it is too close

First Day:  Saturday 22/4/2017,  we left Amman at around 11, we arrived in Istanbul, then immediately (well not exactly immediately, but after 3 hours) took a connecting flight to Marmaris, where the rented boat was waiting for us. 
Upon arrival, it started raining, and when it rains, it pours. We took a minibus to Marmaris, and it took around 1 and a half hours to reach our destination, it was dark and we could not see anything on the way.,  When we arrived at the Marina, it was still pouring rain and there was nobody there. We knew the name of our boat (PEARL) and we luckily found it.  We were soaking wet, and to my pleasant surprise, the boat was equipped with 4 small bedrooms. Each bedroom is very small, equipped with a bathroom (so-called bathroom, to give you an idea, it is smaller than the bathroom of commercial aircraft, except it has a shower as well).  The boat tips badly with wind and gets really scary at times


Forgot to mention that it was also cold, really cold. I had to wear my CASHMERE blouse to get warm in addition to the woolen blanket that you can see in the picture. Notice that the window is located on the ceiling. As for your belongings, there is a small area on the right, that you need to manage.  I was tired and even though the guys wanted to go to a restaurant (pub to be honest) I declined as it was too wet to venture into such things, and I slept like a baby.

The morning after:

Husam keeps shouting. This is a habit of his, so we had to wake up early, it was not raining anymore, but was still cold.  Well, I am pleased to learn that there is a public WC with a shower area. it was spacious and clean, and without any reluctance, I decided to use the public WC rather than the in-boat alternative.  The in-boat alternative is built for people who are not tall, i am 191 cm tall and hence not the perfect fit to use the bathroom with its miniature shower area

Ammar Sajdi



Sunday, March 19, 2017

Fail to login to Oracle BIEE analytics page even though you know for sure that your analytics username and password are correct

This is a purely technical post , that i am writing primarily to remind myself about many issues that would face anyone trying to login to the oracle BI analytics page  (http://server:7001/analytics )


Two log files that you need to inspect

nqServer.log  located at  
C:\Middleware\instances\instance1\diagnostics\logs\OracleBIServerComponent\coreapplication_obis1

and swlog1 located at
C:\Middleware\instances\instance1\diagnostics\logs\OracleBIPresentationServicesComponent\coreapplication_obips1

in the swlog1 i got errors similar to 

[2017-03-19T19:18:10.000+03:00] [OBIPS] [ERROR:1] [] [saw.security.odbcuserpopulationimpl.getbisystemconnection] [ecid: 00ieQim1zLuFw0zlbq0CBz3aJzi3jwIx600010^000000,0:2487] [tid: 3188] Authentication Failure.
Odbc driver returned an error (SQLDriverConnectW).
State: 08004.  Code: 10018.  [NQODBC] [SQL_STATE: 08004] [nQSError: 10018] Access for the requested connection is refused.
[nQSError: 43113] Message returned from OBIS.
[nQSError: 43126] Authentication failed: invalid user/password. (08004)[[
File:odbcuserpoploaderimpl.cpp
Line:995
Location:
    saw.security.odbcuserpopulationimpl.getbisystemconnection


and in the nqServer  i got errors similar to 

[2017-03-19T19:18:09.000+00:00] [OracleBIServerComponent] [ERROR:1] [] [] [ecid: 00ieQim1zLuFw0zlbq0CBz3aJzi3jwIx600010^000000] [tid: b48] Error Message From BI Security Service: SecurityService::authenticateUserWithLanguageUnexpected error authenticating user {0}
[2017-03-19T19:18:09.000+00:00] [OracleBIServerComponent] [ERROR:1] [] [] [ecid: 00ieQim1zLuFw0zlbq0CBz3aJzi3jwIx600010^000000] [tid: b48]  [nQSError: 43126] Authentication failed: invalid user/password.



there are many reason why you get authentication failed   with [nQSError 43126]

in my case the problem was related to the fact that not all JDBC data sources where deployed on both the BI cluster, and the AdminServer Cluster, they were all deployed on the BI Cluster, and some on the AdminServer. Once , i deployed the jdbc data sources on the AdminServer in addition to the BI Cluster, and then rebounced the services, the problems disappeared.

However, other caused are present, i found a very helpful  document on metalink that summarizes all possible problems that are manifested by

nQSError: 43126] Authentication failed: invalid user/password.

please check the document below

Note: Such error is caused by OBIEE trying to access the database, because if you look above , there is ODBC and SQL involved  (repeated here)
  "Odbc driver returned an error (SQLDriverConnectW).
State: 08004.  Code: 10018.  [NQODBC] [SQL_STATE: 08004] [nQSError: 10018] Access for the requested connection is refused".  


That is why i was thinking Data Source immediately



OBIEE 11g: Error:" [nQSError: 43126] Authentication failed: invalid user/password." (Doc ID 1472848.1)


Wednesday, January 18, 2017

أخترت لكم


عمان  كانون ثاني ٢٠١٧ 

اجد نفسي، وبعد ان خال لي اني هجرت الكتابة في هذا البلوج بضع من الزمان ، اعاود طرق بابة لجمال ما قرأت وذلك بعد ان فشلت مقامة عدم نشره هنا

من اقوال جبران خليل جبران

"البعض نحبهم لكن لا نقترب منهم ، فهم في البعد أحلى وهم في البعد أرقى وهم في البعد أغلى

والبعض نحبهم ونسعى كي نقترب منهم ونتقاسم تفاصيل الحياة معهم ويؤلمنا الابتعاد عنهم ويصعب علينا تصور الحياة حين تخلو منهم.

 والبعض نحبهم ونتمنى أن نعيش حكاية جميله معهم ونفتعل الصدف لكي نلتقي بهم ونختلق الأسباب كي نراهم ونعيش في الخيال أكثر من الواقع معهم

 والبعض نحبهم لكن بيننا وبين أنفسنا فقط فنصمت برغم الم الصمت فلا نجاهر بحبهم حتى لهم لان العوائق كثيرة  والعواقب مخيفه ومن الأفضل لنا ولهم أن تبقى الأبواب بيننا وبينهم مغلقه

والبعض نحبهم فنملأ الأرض بحبهم ونحدث الدنيا عنهم ونثرثر بهم
 في كل الأوقات ونحتاج إلى وجودهم كالماء ..والهواء ونختنق في غيابهم لابتعاد عنهم

 والبعض نحبهم لأننا لا نجد سواهم وحاجتنا إلى الحب تدفعنا
 نحوهم فالأيام تمضي والعمر ينقضي والزمن لا يقف ويرعبنا بأن نبقى بلا
 رفيق 

والبعض نحبهم لان مثلهم لا يستحق سوى الحب ولا نملك أمامهم سوى أن نحب فنتعلم منهم أشياء جميله ونرمم معهم أشياء كثيرة ونعيد طلاء الحياة من جديد ونسعى صادقين كي نمنحهم بعض السعادة

 والبعض نحبهم لكننا لا نجد صدى لهذا الحب في قلوبهــم فننهار و ننكسر و نتخبط في حكايات فاشلة فلا نكرههم ولا ننساهم ولا نحب سواهم ونعود نبكيهم بعد كل محاوله فاشلة

 والبعض نحبهم ويبقى فقط أن يحبوننا مثلما نحبهم"

من اقوال جبران خليل جبران


عمار 

Fundamentals of Software Testing

Originally posted on jan , 23 2009, Published again on Sept,18,2024 extracted completely from    http://testingsoftware.blogspot.com/2005/1...