How should I test HTML generated for a web page? [closed] - html

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have some HTML on a page that has a bunch of tables and data (it's a report page). This is all legacy code, so no harassment necessary on the use of tables.
Given that it is legacy code, it is fragile, and we want to confirm that the table looks like we want (number of columns, rows, and the data inside of them are accurate).
My first inclination is to use selenium web driver and run through everything that way (Page Object Pattern), but a co-worker suggested that I just view source of the page, copy the table in question, and then just use this to do a string comparison in the test.
My initial thoughts on his proposal is that it is not a good test because you're starting with the answer and then writing a test to make sure you get that answer (essentially non-TDD). But I'm not sure that's a good enough answer in this case.
How should I test HTML table to make sure all columns, rows are how we like, in addition to the contents of each cell?

It depends. String matching sounds like Approval Testing, depending on just how dynamic the table is that could be fine.
If I already had Selenium tests running I'ld stick with what I have. Using findElements to count and verify the various columns, rows, and values.
Re: your comment if you cannot convince the developers to add ids, names, or something to make your job easier and you do go the Selenium route then xpath is probably what you will want to use. We've created utility methods to help in these sort of situations:
public boolean isLabeledTextPresent(String label, String text) {
WebElement element = findElement(By.xpath("//tr/th/label[contains(text(), '" +
label + "')]/ancestor::tr/td"));
String labeledText = element.getText().trim();
return labeledText.contains(text);
}

I think both methods are valid, it really depends on what you are trying to do and what advantages/disadvantages work best for you.
It would take a little work (depending on you or your teammates skill sets and experience) to write a Selenium script to scrape the table and verify certain things.
Advantages:
Once completed, it will validate very quickly and will be less fragile than method #2.
Disadvantages:
This is dependent on how quickly you can write a script and how easily you are able to validate all the things you want to validate. If all you want is # cols/rows and cell content, that should be very easy. If you want to validate things like formatting (size, color, etc.) then that starts to get a little more complicated to do through code.
It would be super easy to copy/paste HTML and validate against that. The problem is, as you pointed out, you are starting with the answer in some respects. You can get around that by validating that the HTML source for the table is correct. That will have to be done manually but once you get that, you can open the page and compare source of the table vs what you have validated.
Advantages:
You will be able to tell when anything changes... formatting, data, # cells, ... everything.
Disadvantages:
You will be able to tell when anything changes... lol. Your test will fail when anything is changed which will make the test very fragile if you expect that the table will ever get updated. If it gets updated, you will have to revalidate all the HTML for the table which could get to be a tedious process depending how often you expect this to happen. One thing that will help with this validation is to use a diffing tool... you can quickly determine what has changed and validate that instead of having to validate everything each time there is a change.
I would lean towards #1, write the script. It will be less fragile and as long as someone has the right skills shouldn't be that big of a task.
EDIT
You didn't specify what language you are working in but here's some code in Java that hopefully will point you in the right direction if you choose to write a script.
WebElement table = driver.findElement(...));
List<WebElement> rows = table.findElements(By.tagName("tr"));
Assert("Validate expected number of rows", rows.size(), expectedNoOfRows);
for (int row = 0; row < rows.size(); row++)
{
List<WebElement> cells = rows.get(row).findElements(By.tagName("td"));
Assert("Validate expected number of cells in row " + row, cells.size(), expectedNoOfCells[row]);
for (int cell = 0; cell < cells.size(); cell++)
{
Assert("Validate expected text in (" + cell + "," + row + ")", cells.get(cell).getText().trim(), expectedText[cell][row]);
}
}
You could do something like this at a basic level. If you want to get more fancy, you could add logic that looks for specific parts of the report so you can get a "landmark", e.g. Summary, Data, ... making headings up ... so you will know what to expect in the next section.
You could run a variation of this code to dump the different values, number of rows, number of cells in each row, and cell contents. Once you validate that those values are correct, you could use that as your master and do comparisons vs it. That will keep you from false fails on comparing straight HTML source. Maybe it's something in the middle between a script and text comparison based on HTML source.

Related

How to create quasi-copy of a file [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 months ago.
Improve this question
I would like to create quasi-copy of my directory with sensitive data.
Then I would like to share this quasi-copy with others to provide so called 'real data'.
This 'real data' would allow others to do tests in matters related to storage performance.
My question is how to create copy of any file ( text, jpeg, sqlite.db, ... ) that will not contain any of its original data, but from point of view of compression, de-duplication and so on would be very similar.
I appreciate any pointers to tools, libs that helps with creating such quasi copy.
I appreciate any pointers what to measure and how to measure similarity of original file and its quasi copy.
I don't know whether a "quasi-copy" is an established notion and whether there are accepted rules and procedures. But here is a crude take on how to "mask" data for protection: replace words by equal-length sequences of (perhaps adjusted) random characters. One cannot then do a very accurate storage analysis of real data but that has to suffer after any data scrambling.
One way to build such a "quasi-word," wrapped in a program for convenience
use warnings;
use strict;
use feature 'say';
use Scalar::Util qw(looks_like_number);
my $word = shift // die "Usage: $0 word\n";
my #alphabet = 'a'..'z';
my $quasi_word;
foreach my $c (split '', $word) {
if (looks_like_number($c)) {
$quasi_word .= int rand 10;
}
else {
$quasi_word .= $alphabet[int rand 26];
}
}
say $quasi_word;
This doesn't cut it at all for a de-duplication analysis. For that one can replace repeated words by the same random sequence, for example as follows.
First make a pass over the words from the file and build a frequency hash, of how many times each word appears. Then as each word is processed it is first checked whether it repeats, and if it does a random replacement is built only the first time and later that is used every time.
Further adjustments for specific needs should be easy to add.
Any full masking (scrambling/tokenization...) of data of course cannot allow a precise analysis of compression of real data using such a mangled set.
If you know specific sensitive parts then only those can be masked and that would improve the accuracy of the following analyses considerably.
This will be slow but if a set of files need be built once in a while it shouldn't matter.
A question was raised of the "criteria" for the "similarity" of masked data, and the question itself was closed for lack of detail. Here is a comment on that.
It seems that only "measure" of "similarity" is simply whether the copy behaves the same in the storage performance analysis as the real data would. But, one can't tell without using real data for that analysis! (What clearly would reveal that data.)
The one way I can think of is to build a copy using a candidate approach and then use it (yourself) for individual components of that analysis. Does it compress (roughly) the same? How about de-duplication? How about ...? Etc. Then make your choices.
If the used approach is flexible enough the masking can then be adjusted for whichever part of analysis "failed" -- the copy behaved substantially differently. (If compression was very different perhaps refine your algorithm to study words and produce more similar obfuscation, etc.)

How to detect redundant piece of code containing array?

The lecture for my Java class has this piece of code:
for (int i=0; i<arr.length; i=i+10){
if(i%10 == 0){
System.out.println(arr[i]);
}
}
If you start at 0 and then go 10, 20, etc. Why do you need the if condition? Naturally all of these numbers divide by 10.
It's redundant. The only way it could have an effect is when the array length is close to the Integer max value and you're causing overflows by adding 10, but then your code would loop infinitely anyway (or crash when accessing negative array values).
To me the code in the if condition might have 2 reasones:
It is a way to monitor the progress of the function (although since the condition of the for loop is i=i+10 instead of i++, it is less meaningful in this case). This is very normal when we are using some script to execute a task that is dealing with a lots of data (normally in single process, and take some time). By printing out the progress periodically we are able to know (or estimate) how many data has been read/wrtie, or how many times have the codes in the loop has been executed, in this case.
There might be more code added in the for loop, which might modify i. In this case, i%10 == 0 will be meaningful.
In other words, without any more context it does seems like the if condition is redundant, in this case.
To answer the question of the title, here's what we usually do. First, have the code review done by someone else before you merge your branch. Having another fellow to review your codes are good practise as they could give you a fresh mind on correctness and code style. Second, if you find something that is suspecious but not sure (for example, the "redundant code" you think here), wrote unit tests to cover the part of code that you would like to change, make the changes and rerun the unit tests and see if you still get what is expected.
Personally I haven't heard of any tools that is able to detect "redundant code" as the example here, as "redundant" might not be "redundant" at all under different circumstances.

Calculating in Google Spreadsheet

I'm very new to Google spreadsheet and I've played around with functions but I'm not too sure how to create what I'm looking for.
I'm trying to make a calculator for a game where people can input their settings and based on their settings and the desired stats they want their hero to be by the end it will spit out results.
The problem I'm having is I'm not sure what formula you use. Here is the document:
https://docs.google.com/spreadsheets/d/1X5Mb24c8C4SblrsSBSoFuf8sB3fomM_X20isJO8KHLI/edit?usp=sharing
I was thinking IF D4 is 2★ and they want to get to +5 then it would follow I16's Rules.
Not sure if this makes a whole lot of sense. But basically Im trying to get
IF D4 = 2★ Then Results.
BUT if D4 = 3★ Then Different Results.
Not sure how to do this on one cell. If further explaination is needed let me know, The game is based off of 7knights if that helps at all.
Still a little bit confused on what your if statements are to contain, and what the dependent results should be - but from your last statement in the question it sounds like your just wanting a if statement to demonstrate the varying conditions?
ie:
=IF(D4="★★","RESULTS",IF(D4="★★★","OTHER RESULTS","OTHERWISE DEFAULT"))
I can easily modify this with real results/examples if you help me to understand what you actually want the end result to look like.

Three rows of almost the same code behave differently

I have three dropdown boxes on a Main_Form. I will add the chosen content into three fields on the form, Form_Applications.
These three lines are added :
Form_Applications.Classification = Form_Main_Form.Combo43.Value
Form_Applications.Countryname_Cluster = Form_Main_Form.Combo56.Value
Form_Applications.Application = Form_Main_Form.Combo64.Value
The first two work perfectly but the last one gives error code 438!
I can enter in the immediate window :
Form_Applications.Classification = "what ever"
Form_Applications.Countryname_Cluster = "what ever"
but not for the third line. Then, after enter, the Object doesn't support this property or method error appears.
I didn't expect this error as I do exactly the same as in the first two lines.
Can you please help or do you need more info ?
In VBA Application is a special word and should not be used to address fields.
FormName.Application will return an object that points to the application instance that is running that form as opposed to an object within that form.
From the Application object you can do all sorts of other things such as executing external programs and other application level stuff like saving files/
Rename your Application field to something else, perhaps ApplicationCombo and change your line of code to match the new name. After doing this the code should execute as you expect.
Form_Applications.Application is referring to the application itself. It is not a field, so therefore it is not assignable (at least with a string).
You really haven't provided enough code to draw any real conclusions though. But looking at what you have posted, you definitely need to rethink your approach.
It's to say definitely but you are not doing the same. It looks like you are reading a ComboBox value the same (I will assume Combo64 is the same as 43 and 56) but my guess is that what you are assigning that value to is the problem:
Form_Applications.Application =
Application is not assignable. Is there another field you meant to use there?

Is it bad to perform two different tasks in the same loop? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I'm working on a highly-specialized search engine for my database. When the user submits a search request, the engine splits the search terms into an array and loops through. Inside the loop, each search term is examined against several possible scenarios to determine what it could mean. When a search term matches a scenario, a WHERE condition is added to the SQL query. Some terms can have multiple meanings, and in those cases the engine builds a list of suggestions to help the user to narrow the results.
Aside: In case anyone is interested to know, ambigous terms are refined by prefixing them with a keyword. For example, 1954 could be a year or a serial number. The engine will suggest both of these scenarios to the user and modify the search term to either year:1954 or serial:1954.
Building the SQL query and the refine suggestions in the same loop feels somehow wrong to me, but to separate them would add more overhead because I would have to loop through the same array twice and test all the same scenarios twice. What is the better course of action?
I'd probably factor out the two actions into their own functions. Then you'd have
foreach (term in terms) {
doThing1();
doThing2();
}
which is nice and clean.
No. It's not bad. I would think looping twice would be more confusing.
Arguably some of the tasks might be put into functions if the tasks are decoupled enough from each other, however.
I don't think it makes sense to add multiple loops for the sake of theoretical purity, especially given that if you're going to add a loop against multiple scenarios you're going from an O(n) -> O(n*#scenarios). Another way to break this out without falling into the "God Method" trap would be to have a method that runs a single loop and returns an array of matches, and another that runs the search for each element in the match array.
Using the same loop seems as a valid optimization to me, try to keep the code of the two tasks independent so this optimization can be changed if necessary.
Your scenario fits the builder pattern and if each operation is fairly complex then it would serve you well to break things up a bit. This is waaaaaay over engineering if all your logic fits in 50 lines of code, but if you have dependencies to manage and complex logic, then you should be using a proven design pattern to achieve separation of concerns. It might look like this:
var relatedTermsBuilder = new RelatedTermsBuilder();
var whereClauseBuilder = new WhereClauseBuilder();
var compositeBuilder = new CompositeBuilder()
.Add(relatedTermsBuilder)
.Add(whereClauseBuilder);
var parser = new SearchTermParser(compositeBuilder);
parser.Execute("the search phrase");
string[] related = relatedTermsBuilder.Result;
string whereClause = whereClauseBuilder.Result;
The supporting objects would look like:
public interface ISearchTermBuilder {
void Build(string term);
}
public class SearchTermParser {
private readonly ISearchTermBuilder builder;
public SearchTermParser(ISearchTermBuilder builder) {
this.builder = builder;
}
public void Execute(string phrase) {
foreach (var term in Parse(phrase)) {
builder.Build(term);
}
}
private static IEnumerable<string> Parse(string phrase) {
throw new NotImplementedException();
}
}
I'd call it a code smell, but not a very bad one. I would separate out the functionality inside the loop, putting one of the things first, and then after a blank line and/or comment the other one.
I would look to it as if it were an instance of the observer pattern: each time you loop you raise an event, and as many observers as you want can subscribe to it. Of course it would be overkill to do it as the pattern but the similarities tell me that it is just fine to execute two or three or how many actions you want.
I don't think it's wrong to make two actions in one loop. I'd even suggest to make two methods that are called from inside the loop, like:
for (...) {
refineSuggestions(..)
buildQuery();
}
On the other hand, O(n) = O(2n)
So don't worry too much - it isn't such a performance sin.
You could certainly run two loops.
If a lot of this is business logic, you could also create some kind of data structure in the first loop, and then use that to generate the SQL, something like
search_objects = []
loop through term in terms
search_object = {}
search_object.string = term
// suggestion & rules code
search_object.suggestion = suggestion
search_object.rule = { 'contains', 'term' }
search_objects.push(search_object)
loop through search_object in search_objects
//generate SQL based on search_object.rule
This at least saves you from having to do if/then/elses in both loops, and I think it is a bit cleaner to move SQL code creation outside of the first loop.
If the things you're doing in the loop are related, then fine. It probably makes sense to code "the stuff for each iteration" and then wrap it in a loop, since that;s probably how you think of it in your head.
Add a comment and if it gets too long, look at splitting it or using simple utility methods.
I think one could argue that this may not exactly be language-agnostic; it's also highly dependent on what you're trying to accomplish. If you're putting multiple tasks in a loop in such a way that they cannot be easily parallelized by the compiler for a parallel environment, then it is definitely a code smell.