Thursday, August 31, 2017

SQL(and other) Injection testing for beginners

I was testing a piece of our software the other day and came across this. When I first started it took me forever to figure out what was meant by this. Code injection doesn't necessarily have to be SQL that is being executed but can also be javascript or any other type of code that is put into a field in a program that is not supposed to take that kind of information.

What I saw the other day was placing javascript into the place where a name was supposed to be and what would happen is that the javascript would run when loading a page that had that information on the page. That would be a javascript injection attack.

The reason why it is called SQL injection is because at first it was people entering in SQL (the language of databases) in places that shouldn't have it and then they would have access to the database to do what they wanted with it.

"And thatsssss...bad?" (emperor's new groove) yes extremely they now have access to all information that is stored in your database they also have access to manipulate the tables how they want.

When testing for this one thing you want to do is to use different SQL commands in order to test a variety of possible attacks. Here are a few examples of SQL to test input areas of your program

"SELECT * FROM Xtable" Xtable = any table in your database; this tests basic keywords
add "or 1=1" to the previous statement to test against returning all rows in that table
Type text ";Drop Table X;" This will finish the search query and then drop a table in the database

These are just a few and these are only for the SQL based attacks there are other injection attacks like that also has vulnerabilities like this.

The javascript if you type <script> Javascript</script> into your input and it executes the javascript you have a vulnerability.

This is basic (very basic) idea of what javscript injection is and some basic things to how to test for it.

Here are a few pages that explain some more/different ideas on SQL injection.



Friday, August 4, 2017

Clean Code

At work we have been reading and discussing as an engineering department. While I don't agree with everything there are definite aspects of it that I have found extremely helpful when looking at old/legacy code. I would like discuss a few of the points that were most helpful.

1. Naming variables
This is sooo crucial. I have found, no joke, variables called 'a' or 'b' in code. Let me tell you that this is the most annoying thing. Because now I have to spend 30 to 45 minutes (if i'm lucky) trying to find out what the variables are supposed to be. This is especially annoying with parameter variables.
I found it most helpful to pull someone over and ask them if they know what the variables are supposed to represent. That way I get the opinion of someone who has know idea what the code is actually supposed to do. I also found it helpful to refactor after I finish writing the function or segment of code to make sure the variables store what they are supposed to store.

2. Functions doing just one thing and naming functions
You would not believe how helpful this is. I was recently working in a language called cold fusion and I kid you not there was a function not a class that basically was an API. That is hopefully an extreme example but none the less having your function do just one thing is super helpful for testing, refactoring and using the function itself. One of the things this does is keep your parameter list down which makes usage significantly easier to navigate. The naming of functions is also something you should keep in mind when righting clean code. make sure your function is named what it is doing

3. Abstract out all the things
You should put things where they go and avoid clumping.What I mean by that is making sure you have your back end code separate from your front end code and connect them with your API's. If you follow number 2 this should be pretty easy to follow. if you do this your code will be the easiest to maintain and to refactor later on.

4. refactor often and make sure your code is covered with tests (of some sort)
The reason i put these together is if you don't have the tests then you will not be able to refactor with confidence. Refactoring often will help you avoid potential issues. This is how you convert legacy code to clean code. So if you don't have tests already write them, then start the refactor process. I would suggest starting this sooner rather than later because of the potential technical debt that you could be accruing.

So these points and this book more refer to software developers when stating the various points and as it is true that these points do refer mostly to developers I have found some of the dirtiest code written by SQA for automation tests. So I implore ANYONE who writes code to make sure that you write clean code.

Saturday, July 22, 2017

Automating PDF's through Adobe API In Ruby

In the last couple of weeks I have been spending some time automating some pdf tests. It has definitely been a learning experience as I had never done anything like that before. Just some background I was doing this with Ruby in the Selenium framework. I started by going through some various gems out there that give access to different parts of the pdf. I found that for my specific use it would be good to use adobe api.

Some quick things about it I found useful.

One is the relationships between the different entities that are created such as the .app vs the .avdoc and the .activedoc. This relationship diagram I found very helpful in figuring out what was going on.

Second is to realize that pdfs are javascript, or at least a type of javascript, in the background. This will help because you can get the js object of the pdf and check various attributes as well as modify stuff on the fly in the app window itself, such as advanced searches. Here is a part of the code that I wrote using the getJSObject and searching things. @@js = AcroExch.AVDoc.getPDDoc.getJSObject

Third and last is get it right the first time. Part of the reason I decided to use this is because it was built, or so I thought. I ended up having to rewrite stuff as well as figuring out what the heck the previous guy was talking about. It is so hard to go into code like this and try to figure out all the different entities and API calls. This one is really true about any code you write, this just seemed especially irking to me because the story was supposed to be a quick 1pt story and it ended up taking me longer because I had to rewrite most of the functionality in our pdf class.

Here is part of my pdf.rb

require 'win32ole'

class Rect
  def initialize upper_left_x, upper_left_y, lower_right_x, lower_right_y
    @upper_left_x = upper_left_x
    @upper_left_y = upper_left_y
    @lower_right_x = lower_right_x
    @lower_right_y = lower_right_y

  def position
    {x: upper_left_x, y: upper_left_y}

  def upper_left_x

  def upper_left_y

  def lower_right_x

  def lower_right_y

  def inspect
    "#{@upper_left_x}, #{@upper_left_y}, #{@lower_right_x}, #{@lower_right_y}"

class Pdf
  include OpenFileDialog

  @@pdf_app = nil
  @@pdf_pddoc = nil
  @@pdf_avdoc = nil
  @@js = nil
  @@pdf_bookmark = nil
  @@pdf_page = nil
  @@pdf_annot = nil
  @@pdf_link = nil
  @@pdf_page_view = nil
  @@pdf_active_doc = nil

  def initialize
    @@pdf_app ='AcroExch.App') if @@pdf_app.nil?

  def open_pdf filepath
    @@pdf_avdoc ='AcroExch.AVDoc')
    if not @@pdf_avdoc.Open(filepath,"Adobe Acrobat Pro DC")
      error_msg = "Unable to open pdf file with path #{filepath}\n"
      error_msg += "Is the path correct?\n"
      error_msg += "Is the pdf corrupted?\n"
      raise error_msg
    @@pdf_bookmark ='AcroExch.PDBookmark')
    @@pdf_active_doc = @@pdf_app.GetActiveDoc
    @@pdf_page_view = @@pdf_avdoc.GetAVPageView
    @@pdf_pddoc = @@pdf_avdoc.GetPDDoc
    @@js = @@pdf_pddoc.GetJSObject
    pdf_window = title: /Adobe Acrobat Pro DC/i
    return self

  def open_pdf_from_resources filename
    self.open_pdf env['resource_dir'] + '/' + env[filename]

  def open_downloaded_pdf filename
    file_path = get_full_file_path filename
    self.open_pdf file_path

  def get_full_file_path partial_path
    Find.find("#{ENV['USERPROFILE']}/downloads/") do |path|
        if path.include? partial_path
            return path

  def cleanup_downloads partial_path
    Find.find("#{ENV['USERPROFILE']}/downloads/") do |path|
        if path.include? partial_path
          File.delete(path) if path.include? partial_path

  def verify_pdf_doc_is_opened
    unless pdf_doc_is_opened?
      raise 'There is no pdf document opened'

  def pdf_doc_is_opened?

  # advanced search matching multiple words works when searching with more than one word pass in the words in the same string separated by a space
  def advanced_search search_text, match_all_words:true, match_any_word:false,match_phrase:false,metadata:false
    if match_all_words = "MatchAllWords";
    elsif match_any_word = "MatchAnyWord";
    elsif match_phrase = "MatchPhrase";
    end = metadata

    # there are more options available that are not coded in;

Monday, June 26, 2017

Ruby + Selenium Webdriver basics

Here are a couple basic things to know when writing an automated test in ruby using selenium webdriver.

First is Mapping a page.
I know this may seem redundant but it actually makes for reading a whole lot easier.

Second is adding the right elements.

The first snippet are the list of elements created. The second is actual code to make a slider element. Like mapping this may seem trivial but improves readability which in turn saves time and money

Third is clear concise test
This is important because for every extra step you have in there it slows down performance which costs extra money. When it fails it also makes it difficult to debug.

Fourth write useful functions
If you know you are going to be using a same step(s) over and over. Write a function or class that will do it. This will add to clarity and readability.

Friday, May 26, 2017

The Value of Coding as a SQA

This is a very controversy topic and it kind of goes hand in hand with manual testing vs automation testing (which I have written on before).

What is it like black box testing? Is it fun setting up your environment every time you to be a specific way to be able to test a specific feature a specific way?

The short answer is black box testing is a valuable way to test because it more mimics users. Manually doing this is sometimes the only way to test some features especially new features. There is however a way to set environments or automate certain sections of testing that could alleviate your headaches in remembering how to set up a certain environment. It is coding it out to have it automate setting up an environment in Selenium or Ruby or whatever other automation tool you can think of. The issue of course is that you need to know how to use these tools, which for a lot of tools requires coding.

I go back to the title of this post. Is it valuable for SQA to know coding? Absolutely, they can by doing this learn how to use scripts to set up environments they can learn how to completely automate tests, which in turn saves time and money.
Another great reason for SQA to learn to code is that they can Pair-Program. This is a great way of eliminating bugs as they are being coded.

For example, the other day I was pair programming and was able to bring up a use case that was not thought of because I was able to follow the code and the logic of what was being coded up.

In the end it is up to you to figure out whether you can learn to code and if you could set up any form on automation or pair programming, but I would recommend it. It is, in my opinion, well worth the time to learn because it saves both headaches and time

Friday, February 17, 2017

Testing with Flowcharts

What can this program do? I don't know follow the actions and see. This is what I was told the when I went in for an interview and they told me to find as many bugs as I can ad write a bug report with those bugs. The first thing I thought of was the idea of flowcharts.

Flowcharts are such a nice easy way to follow the various possible actions that a program can take. Which then you can use to create test plans and for various other testing purposes.

Image result for flowchartLots of people understand the idea of a flowchart but not how to implement one. The biggest issues in implementing a flowchart are two fold. 
One it is hard to follow a program and all the possible actions you could take. This can be so tedious if it is a complicated program, but there is a way, or technique I have found in making this a tad easier. Make smaller flowcharts. If you think about this it should be pretty obvious but lots of people want to just make the flowchart for the whole program all at once. It is so much easier to break it in to sub tasks that you then can connect later to display the flow of the program.

Two, the symbols of the flowchart. This one is not as big of deal because you can always look of the various symbols, but there is an easier way. There are programs out there that show and name the various shapes that you can use in your flowchart such as LucidChart or Microsoft Visio. There are others but these are the 2 best that I have used.

Just to make things a tad simpler I will go through the basic couple shapes that should get you started on your flowchart.

Flowchart Line.svg   This is directional line which indicates the direct you should go from one shape to the next

Flowchart Terminal.svgThis is the terminal shape they are the beginning and ending piece to almost every flowchart

Flowchart Process.svg This is a process block, which is used to show when something needs to be performed

Flowchart Decision.svg This is the decision block which is used when there is a conditional statement (such as true or false or yes or no)

These are the 4 most commonly used shapes in creating flowcharts. Flowcharts can make everyone's life easier. 

Monday, January 2, 2017

New Year New Challenges

Learning, according to Merriam-Webster is "the acquisition of knowledge or skills through experience, study, or by being taught". We learn new things on a daily basis, whether it's how to cook ham and bean soup on Facebook, or new studies that tell us how long it took dinosaur eggs to hatch, or how to use and work with new types and avenues of technology. Since technology in particular changes on a daily basis it is one thing that requires continual learning in order to keep up with updates and changes. 

This is particularly relevant when it comes to software testing. Because automation testing is a relativity a new field there is still so much potential that has still not been reached in this field. The benefits of being able to reach this potential would cut down on the need of such intense manual testing and open up manual testers to be able to focus more on exploratory testing and allow for more coverage of the software, which in turn would create more efficient and better software overall. If manual testers didn't have to ever do the same test twice, they could find new ways and better ways to provide maximum coverage of a particular software and reduce mistakes and oversights. 

Better testing would allow for better technology that will effect all of our lives. Whether in the medical field or with fitness apps or with banking technology better testing will protect us as well as allow for the technology to do its job better. 

To advance testing we must figure out more efficient ways to do testing, whether it be by creating new methodologies or by creating new technologies, which is why learning as much as we can about testing and about new technologies benefits all of us. 

We need to keep learning and being proactive in finding new and better ways of doing things. As we learn and continually develop new software testing methodologies and frameworks in order to keep up with the advancing programs we can better help accommodate for the advancement of technology.