Grey Smith

+ Follow
since May 24, 2014
Cows and Likes
Total received
In last 30 days
Total given
Total received
Received in last 30 days
Total given
Given in last 30 days
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Grey Smith

I enjoyed reading this thread. Thanks for your enthusiasm Junilu! Love it when people really care about the code they write and have deeply thought about it.  I would say those those qualities, along with being willing to admit you're wrong (and throw away any code you've written if a better solution comes along), and question your own beliefs, make for a great, productive coding environment.
1 year ago
Junilu - quite right. I should totally try out TDD a couple more times, at least when I'm writing behavioral tests...
I think there's a big difference between behavioral tests -- does some chunk of code act correctly given some input -- and what I refer to as "unit" tests, which usually only test individual functions or at most 2-3 functions together. My experience has been largely with the latter, so I can speak to their utility. Behavioral tests require a different mindset and I unfortunately haven't been able to write many of them because the codebase at my job is not designed for it. I'd love to be able to write a mix of behavioral tests and unit tests on a future project. Having test cases in mind -- knowing the right behavior -- is the first thing you need to know. If writing behavioral tests first forces developers to consider thoroughly what they will write and why, that would be wonderful.
1 year ago
Reading this:

In theory, you could perform regression testing even on a functionally decomposed system. In practice, the complexity of that task would set the bar very high. The sheer number of the functional components would make testing all the interactions impractical. The very large services would be internally so complex that no one could effectively devise a comprehensive strategy that tests all code paths through such services. With functional decomposition, most developers give up and perform just simple unit testing. Therefore, by precluding regression testing, functional decomposition makes the entire system untestable, and untestable systems are always rife with defects.

I don't think I quite get what you're saying. Testing all code paths is always impossible for any fair-sized application. But doing manual regression testing on any program is as simple as using it in its most common ways -- does it start up? Does it do Task A and B? What if I give it bad input? That kind of manual testing is unavoidable and forms the backbone of development. If you're referring to integration (automated) tests -- my experience is remarkably different. I've worked on several projects with minimal bugs and no integration tests, because developers religiously practice manual testing and code reviews.
1 year ago
I think the question is why are unit tests considered essential. What makes them important to write if they provide very little value as actual tests in terms of finding bugs? Why are unit tests preferable to  behavioral tests and integration tests?
I don't know if we should really call unit tests "tests," because it implies that they exercise the code. I've found dozens of bugs by manual testing and reading code, and probably less than ten from unit tests.
I consider unit tests important because they implicitly ask developers to write simple, short code that has a small number of readily understandable dependencies. If it's difficult or cumbersome to write a unit test, it's strong evidence that there's something wrong with the code being tested (or the dependencies of that code or of the test code), and developers should immediately fix that, rather than add layers of complexity to a unit test. Of course, if developers don't have this mentality or don't understand how to improve their code, then unit tests are a waste of time, and conversely (though far more rarely), if code is written well enough to start out with, then unit tests won't promote any changes to the source code, which removes most of their utility.
1 year ago
What a great thread. I love how the focus is always on making the code easy to understand. If a long variable name is necessary to understand the code, then a long variable name is best, but as mentioned, it may be possible to refactor or place the variable in such a context so that a long name is no longer necessary to understand what the variable means. And the devil is in the details; without seeing and understanding the code in depth no good specific recommendations can be made.
2 years ago
Hi Wallace, I have a silly question and some serious ones. What's your favorite tag? Are there any tags that seems to be non-starters ( <dialog> <template> ?) , or that browsers can't get standardized on (like the different vendor-specific styles on <progress> ) ? Do you think that most companies/developers are ignoring HTML5 tags because they don't see the value in ARIA compliance and a semantic web? It seems like all the huzzah goes to Javascript frameworks and CSS gimmicks.
It might be whitespace changes. One version has a space and another doesn't; or one version has a tab character and the other doesn't; or one version has a Mac carriage return and the other has a Windows carriage return. Usually IDEs have an option to set what kind of carriage return you want in your project, and everyone who's working on the project should use the same kind of carriage return. On the command line, the command you can use to tell the difference is:

git diff --check

If you have colors configured right on the console you can then see the differences, and it'll also tell exactly what the whitespace differences are.
Git doesn't have a blanket command like that. It depends on where the "local changes" are.

If you have already commited the changes to your local repository (but not pushed them), you can destroy your last commit by typing:

git reset --hard HEAD~1

and the last commit will be gone. (It's not actually gone -- if you need to get it back, you can do a git reflog to see where it is. Git reflog shows you your history.)
This is considered a dangerous command because it can be difficult to track down the lost commit, and eventually that commit will be garbage collected. But it's also extremely useful, and it's very easy to find the lost commit if you use git reflog right after doing the hard reset. And it is less risky than the other options below.

If you haven't committed the changes, and you don't have any untracked files in the directory (untracked files = files that haven't previously been commited), go to the root directory of the repository, then do:

git reset

to move all files out of the staging area (the place files go before you commit them), and then:

git checkout .

to checkout all files from the last commit (and hence overwrite any changes you've made).

If you only want to get rid of some of the local, uncommited changes, in tracked files, you can run

git checkout -p

and then decide piece-by-pice which changes to keep and which to get rid of. (There are GUIs that make this process a lot easier.)

To get rid of untracked files, you can run:

git clean -f

which will delete them all.
None of these commands are safe in the sense of preserving the changes you made. In order to do that, your primary options are stashing them ("git stash -u", then you can use "git stash list" to view the stashes later), or commiting them (which you can do in a separate branch so that it doesn't get in the way of what you're currently working on).
In terms of reasons not to use testing frameworks -- in my very limited experience, they are often not easy to set up and they do not provide as much functionality as you would get were you to create your own testing set-up (I'm thinking specifically of testing private member functions in Java, although if I remember correctly (??) JUnit tests are supposed to exist in their own package, which really limits what they can do.). There's also a learning curve, which doesn't exist if you write your own tests from scratch.
As a caveat, most of my experience is with Javascript, in which every time I try to set up a testing framework, it takes so long that it is never worth the time. I would rather spend four hours writing thorough tests that execute every time I run the code than spend four hours writing no tests and perhaps not even completing the set-up required to use these vaunted frameworks.

Here's an example of a group of tests I wrote a long time ago without a testing framework. The background is that I wrote a strategy calculator for blackjack, and this tests one specific function (resolveHands) which does a certain set of calculations, along with some other functions along the way. It's not a good test, because (among other reasons) there's no documentation; there's no feedback presented when the test fails; it's not specific enough (it tests too many things); and there's no test description information which could optionally be shown on screen during successful tests; but it does demonstrate what you were asking about, a test without the use of a testing framework.

6 years ago
You should always wrap your XHRs in some kind of framework (one that you build yourself or one that someone has already built) which handles the icky details for you. jQuery is the most well known, but others are available as well, and it's not too difficult to build one yourself (though it's not worth the effort since there are fully functional, extremely well tested frameworks out there (like jQuery's .ajax)). The two primary reasons that you want to use a framework are to avoid code duplication and to ensure that your code is backwards compatible. In a modern web site you will make tons of Ajax requests, and if you write every one from scratch you'll be reinventing the wheel every time. As Bear's slide demonstrates, there are steps you'll have to take for every request -- adding a readystatechange listener, calling .send(), executing some code if the call succeeded (and presumably trying to parse the returned data if it's JSON; and that attempt should always be wrapped in a try-catch block), executing other code if the call failed, and adding a timeout listener (or using a polyfill if that event doesn't exist in the current browser). There's no point in rewriting that code every time since it's going to be the same. Also, whatever framework you use should handle any browser inconsistences for you (which means that you don't even have to be aware of them).

I second Bear's recommendation to always use JSON. Since Javascript is so loosely typed (a variable could be a number, object, function, or something else), many mistakes come from assumptions about the type of variables in your program. (Most of these mistakes are literally impossible to make in a strongly typed language like Java -- your code will be flagged instantly by the IDE and it won't compile.) So pay very close attention to what type your variables are. I use JSDocs with Webstorm -- Webstorm flags function calls which are using variables of the wrong type, which makes it easier to catch mistakes -- though there are probably some free alternative IDEs which provide the same service.
In terms of web sites, I recommend MDN (Mozilla Developer Network). W3schools has information that is incomplete and frequently misleading -- I never go there any more because the information I am looking for is rarely there, and if it is, it's not explained well or at all. MDN has good, detailed articles on HTML, CSS, and Javascript; they also link to the specs, which for me are typically too dense and specific to be useful (though they're the final word), but in dire straights that's where you'll end up. If you are building an actual web site, also check out, which tells you which HTML5/CSS3 features are supported by which browsers. MDN shows a compatibility box to give you an idea, but caniuse has the gory details that you need to make an informed decision.

I learned HTML from Jon Duckett's "Html & CSS." It goes slow enough that's it's pretty easy to pick up; it covers the main points you should know; and it's not a huge book. It's a little old (2011), but I still regularly pull it out to consult because it's so easy to find exactly what I'm looking for. It's a manual that covers the highlights, not a compendium.
but that's not what you're looking for so never mind.
In my limited experience, a status of 0 means that no reply has been received because there is no connection to whatever you're trying to connect to. Kinda like a 404 on steroids. When a server is completely down, and you try to contact it, you'll get that reply.
But as Bear was saying it's an asynchronous request, so you have to listen for the reply; you can't just check it directly after you've made it, because it's not done yet. Something like:

When "Yay my request is done!" prints to the screen, your xhr is finished and you can check xhr.responseText to see what data has been sent back (and xhr.status to check the status code). Note that you must add this event listener BEFORE you send the request; otherwise it won't work. A ready state of 4 indicates that the request is finished.
Fred -- Yes, I agree that programming is 90 % thinking. I'm surprised at how many people don't realize that. However, it is news to me if Agile does help anyone program. It seems a mass of status reports and paperwork (mostly on the computer, but same difference), and short meetings which rarely focus on any details or bring up different points of view.
I don't feel that I need a tool to tell me what the application needs to do. I think that common sense, and talking it over with whoever designed the app and the other people on the team (on a regular basis), can do that job. I know that applications should have as few bugs as possible and be easy to use and maintain. Sometimes figuring out how to make that happen is hard, and on a team it's important to pick a good strategy and have everyone stick by it.
I agree that good communication is important. I'm not going to straight up lie about not knowing something. I'm just not going to volunteer something that might make me appear less competent when I'm new at work. Just not smart to do that -- I don't think anyone can fault me for wanting to keep a job. My judgment of humanity is that we are unfairly judgmental towards other people ( ;) ), and I do not want to be judged.

Andrew -- I read the 16-page Scrum book Jeanne linked to. To me, how ideas are implemented are far more important that what they are in the abstract. Agile and other systems might sound great or awful in the abstract, but what really matters is how people actually use them. I don't put any stock in abstractions, buzzwords, corporate philosophies, etc., because most of the time they don't affect what actually happens day-to-day. Just a bunch of pretty words to dress something up. I have simple ideas about what makes a good workplace and a productive workplace -- open communication (which has to come from the top first as a sign of good faith), committed workers, and a willingness to talk about and accept criticism are three things that come to mind.
I'll glance over at the first chapter. And -- this is a promise -- if I do win a book copy I will read the whole thing.

Junilu --
1) Hm. It's a bit hard for me to separate out company practices and the Agile system since it wasn't explained to me. I feel like we rely too much on applications and virtual documents that are scattered in many places and all have their own logic about them. Learning them all has taken a good deal of time, and I think the tools are too specialized for the work I will be doing. It doesn't seem like there's much freedom yet in the ticket system -- that is, if say one bug is hiding three others, or if a bug and a bunch of other bugs are best dealt with by refactoring a large block of code, I'm uncertain that that would fit neatly in and be accepted. I also think that it's very hard to predict how long some problems will take, and that makes it difficult to be very definite about what will be done in a certain block of time. It's of course necessary to make predictions about what can get done, and without some kind of goal or deadline it'd be too easy for many people to slack off, so I can understand the necessity of structure.
2) …. I'm the new guy. No. Generally even if I don't like something, I won't say it until I'm completely sure about it, because rushing to judgment is very often a stupid thing to do. I'll still rush to judgment in my head, but I'll hold off on saying anything until I'm very sure, 'cause I know I could be wrong. And in the workplace I'm not going to say anything that's going to get anyone upset, unless there's really no choice and it's part of my job to do it.
3) I read the Scrum guide. I also do my best to understand all the tools and systems I'm supposed to use -- read the tutorials if I have time, or listen if someone is willing to explain it, or google it if I need to. Why I do things -- not exactly sure what you mean. I am at work to do what my boss says. That is what most jobs come down to. If you get really lucky then the job is mostly about doing a job, but that's only if your boss is a good boss and supports you in what you have to do instead of getting in the way. I get the feeling that programming is supposed to be professional job where there's lot of velvet on top of the you-are-at-work-to-do-what-your-boss-says, but really, that's what almost everything is.
I'm not trying to slink or be lazy or anything -- I really would like to do a good job.
4) No TDD -- I almost wish there was though because testing and documentation are an afterthought at best. I know there's supposed to be "continuous integration," which if I understand it right (working to produce software that is incrementally better and more functional) seems like common sense to me. Of course you should run your code all the time to make sure it works; it's nice to do tests on it all the time; and it's easier to fix bugs right when they come up -- so you should always strive for a working piece of software so that you know that your code does what you want it to do. Refactoring -- that might have a different meaning in the Agile world. To me it just means improving code that you already have and that already more-or-less works by doing things like adding documentation, making function/variable names more understandable, getting rid of repetitive code, making code more readable, creating new functions/classes to compartmentalize code better and make it easier to add functions/features or fix bugs, etc. I'm totally behind refactoring and when making a project bigger you have to do it on a continuous basis. Another benefit to refactoring is that you become more familiar with the code base, which makes it easier to use it effectively when adding features.

Jeanne -- Well, I really did owe you more courtesy. Even if I do doubt abstract corporate philosophies, I could have been a bit nicer to someone who thinks the opposite of how I do.
Thanks for the link. I'll read over it.
I don't mean to hinder anyone, and I do mean to do a good job. I can put aside how I feel about a particular corporate policy or process and work within its bounds, but when I'm not at work I don't have to act like I like it. I am sorry if I offended you. I acknowledge off the bat I don't know much about Agile, and that I wouldn't be posting if I didn't want to know at least a bit. (and where better to learn from than here where I can at least be honest?) If I felt secure that I would not be judged at work I would ask far more questions there, and probably do much better, but I've had enough bad work experiences to not be so trusting.
I just started a job which is evidently all about Agile -- there are daily "scrum" meetings, big boards with post-its on them which keep getting moved around and talked about, and someone who seems to be like a TicketMaster who gives everyone tickets to do. I've seen "story points" and other bizarre terms, and I'm sick of the phrase "as a user" already. I'm not really sure what's going on; no one has explained anything to me and I consider it too dangerous to admit my ignorance to everyone. (There is no private space at work and hence I can't speak to anyone in private. I find it a very chilling environment.) How can I fake like I know what's going on without having to read a whole book about it? (reading is not billable hours..) I'd rather focus on programming and not "Agile" and a bunch of other "tools" which seem to get in the way of me getting any actual programming done.
Hope you can provide a summary.