When writing automated test cases the first and foremost part is to setup the scaffold or write the framework for writing the test cases. Since now a days we have mostly the websites being built, we will focus on the rough framework for it.
We will use the Page Object Model or called as the POM model for writing the framework. Let's say the website has ten links for ten different pages on it. We are supposed to have one POM for one page each. These pages can be like Home, Products, ContactUs as a class each and so on.
Each of these page objects contain the various objects in that page, say like the links, text boxes, buttons, text fields and so on.
Since the header and the footer menus are a part of almost all the pages in the website, we can declare an abstract Base class which holds these link elements or objects. This Base is then inherited by all the other pages having the header and the footer menus in them.
Drawbacks of POM
When using POM, one must note that when writing tests, each page object has to be initialized and actions be performed on them. When loading/ initializing each page object to the memory, the memory increases and this could slow the automation run(s). In some cases, one may want to perform only one operation on one page and don't have to load the other objects of that page.
Test support libraries usage
Say if you are using NUnit which is a very good framework for writing your automated tests in C#. The browser initialization and using part can be done in the base tests file or tests fixture file and say each tests file/ class can have tests for each web page or similar. These page test(s) file can inherit the base test file and use the browser initialized from it.
Make use of the attributes for tests like the TestCase, Order and all to make the tests report and run better
[TestCase = "Check links on Products page", Order(6)]
public void CheckLinksProductsPage(){}
Advices for better automation
Keep the framework as loosely coupled as possible. What I mean by this is may be not to modular as well like writing independent methods to perform a task. I know may be one or two tests can use it but if not many then it may not be worth having that function at all. Having a method for a login function taking username and password makes sense as many tests can depend on these. This can help perform or even be easy to write robust tests. Otherwise the framework could be cumbersome to use and to write tests with it.
Try data driven approach for running one test with many sets of data. Login to a site can be a very good example of this. User can have positive and negative test data and verify the results in the same test and trying to obey the DRY principle(s).
Data structures used for storing data be light weight for large data sets say like using a simple array object instead of using dictionary or lists or similar which are mutable and these can slow test run(s).
Avoid running UI tests in parallel as these can step on each other and affect the test run(s).