We are using TFS 2010, and we have some very annoying trouble with our dependency/branch management.
At first glance, our problem is quite common. We have AppServer, WebClient and WinClient. Both WebClient and WinClient depend on AppServer. There are two additional limitations:
we prefer to include specific version of used dependency
we prefer to include source code and not binaries, because it's easier to implement and test AppServer changes coming from specific origin, for example, WinClient.
We choose following folder structure:
\
|-AppServer (1)
|-WebClient
|-Dependencies
|-AppServer (2)
|-Sources
|-WinClient
|-Dependencies
|-AppServer (3)
|-Sources
AppServers (2) and (3) are branches (as first-class branch) of AppServer (1). It all works pretty well and matches our development scenario.
Now, there comes a trouble. Suppose we want to implement "branch-per-release" pattern on WebClient, which implies branching whole WebClient hierarchy into another place. We can't do that because TFS2010 does not allow nested first class branches.
To add to the challenge, we envision branch hierarchy (only for WebClient, and we have several other dependent and dependency projects) to be something like this:
WebClient
|-Client1
| |-feature-1
| |-feature-2
| |-v1 Release
| | |-v1 hotfix1
| | |-v1 hotfix2
| |-v2 Release
| |-v1 hotfix1
| |-v1 hotfix2
|
|-Client2
|-feature-1
|-feature-2
|-v1 Release
| |-v1 hotfix1
| |-v1 hotfix2
|-v2 Release
|-v1 hotfix1
|-v1 hotfix2
What are our options? I can think of several:
Convert first-class branches to folders. That will allow us to nest branches, but we will lose tracking and visualization, which I don't like.
We can somehow restructure our code with regards to dependencies. But I tried to think of it for some time and still don't see the answer.
We can switch from code dependencies to binary dependencies, but that will slow our development.
Is there any solution I miss?
Couple of thoughts:
1) You could keep your AppServer Branches separate and un-nested from your WebClients and just use the Workspace Mapping functionality in TFS to emulate something like what you've defined via branching AppServer into the Client branches. This would allow a dev to select the AppServer branch they want and nest it into their local file structure at the right place to facilitate their work.
2) Your statement that development is slowed by having binaries seems like something I would explore further and attempt to measure and quantify. If you have a clear break between your AppServer and the Clients, then I would expect no dependencies between them but instead some proxy code that could be generated by svcutil or some other tool. If this is the case and you are hosting the AppServer in some process and communicating from Clients in another, I don't see why you need to implement your original structure to begin with. It appears to be unnecessary coupling and I would want to know why it was being done in more detail.
Related
Has anyone had any issues with integrating the Merge Modules supplied with the API download .msi file and WiX? Or any other MSI/Installer tool?
When I add for various Features it will accept the Xerces 2.5.0.msm but including any other type of merge modules will fail with the following errors
30>light.exe(0,0): error LGHT0204: ICE27: 'SelfUnregModules' Action in InstallExecuteSequence table in wrong place. Current: Selection, Correct: Execution
30>light.exe(0,0): error LGHT0204: ICE27: Action: 'SelfUnregModules' in InstallExecuteSequence table must come after the 'InstallValidate' action.
30>light.exe(0,0): error LGHT0204: ICE27: Action: 'SelfUnregModules' in InstallExecuteSequence table must come after the 'InstallInitialize' action.
30>light.exe(0,0): error LGHT0204: ICE27: Action: 'InstallFiles' in InstallExecuteSequence table must come before the 'SelfRegModules' action. Current seq#: 4000. Dependent seq#: 2850.
The directory structure looks as so:
<Directory Id="INSTALLDIR" Name="Datacenter">
<Merge SourceFile="$(var.QuickbooksMergeModules)\Xerces2.5.0.msm" Language="$(var.LCID)" DiskId="1" Id="Xerces2.5.0.msm"></Merge>
<Merge SourceFile="$(var.QuickbooksMergeModules)\QBFC13_0.msm" Language="$(var.LCID)" DiskId="1" Id="QBFC13_0.msm"></Merge>
No matter what, cannot get it to work beyond that. I've found some information online regarding including the VC++ 7.0 runtime (I'm assuming I can use later?) but haven't attempted it yet.
Thoughts?
I would carefully read MSI Best Practice #43 and my somewhat counter argument In Defense of Merge Modules.
It's generally best to not use third party merge modules anymore. A standalone MSI brought in through a bootstrapper/chainer is better. If needed, build a stand alone MSI using the merge module and put that into your chainer. The point is, don't contaminate your MSI with problems that can be introduced through the merge module.
The fact that they have custom actions with the name SelfReg in it really makes me wonder about the quality of these modules. Self registration (any form of it) is usually a very bad thing.
I have been working to get a SpecFlow framework in place for my Test environment, now I'd like
to extend the ability to use this for multiple environments. I was wondering if I could do this with BeforeFeature so that I can use Tags to say which environment I want to run, and which tests I'd like to be able to do on any/each environment. Part of the problem I have in
figuring this out is one of the Feature Scenarios I have to run contains an example table that will have different values for Test and Local.
Can I set up something like this in my Step Definition file?
[BeforeFeature("Test")]
public static void BeforeFeature_Test()
{
setupEnvironment("Test");
}
[BeforeFeature("Local")]
public static void BeforeFeature_Local()
{
setupEnvironment("Local");
}
If I have the tags #Test and #Local set up in my Feature files can I
run BeforeFeature like this to get the correct settings I might need
for my tests or environment?
With the Example Table I have something like:
Then I should be able to access <weblinks> pages
#Test
Examples:
| weblinks |
| http://test/url1 |
| http://test/url2|
#Local
Examples:
| weblinks |
| http://local/url1 |
| http://local/url2 |
Can the #Test and #Local tags work for both the Feature tests I want to run and the example tables?
I'm running this in NUnit, and I have my configuration set up with allowRowTests="false" as I noticed someone mentioned on the list before, but that may have been in an earlier SpecFlow, I am using 1.8 in Visual Studio 2010 with WebDriver and C#.
It looks like I can do this, it just took me a bit to understand how to link the two together. The Setup issue is separate, and still an issue, than the Examples issue, but I know how to work the table issue out.
This is an example of one of our acceptance tests:
Feature: Add an effect to a level
In order to create a configuration
As a user
I want to be able to add effects to a level
Scenario: Add a new valve effect to a level
Given I have created a level named LEVEL123 with description fooDescription
And I am on the configuration page
When I click LEVEL123 in the level tree
And I expand the panel named Editor Panel
And I click the Add Valve Effect button
And the popup named ASRAddVal appears
And I click the Add new button
And I fill in these vertical fields
| field name | value |
| Name | Effect123 |
Then I should see the following texts on the screen
| text |
| Effect added : EFFECT123 |
We feel that this is getting a bit to verbose and we want to hear how you reduce steps in Specflow. From what I've read so far, creating specific non-reusable steps is not recommended, so what is considered "best practice" when doing this in SpecFlow?
Update:
What I am trying to say is that I've learned that you should try to create generic steps in order to re-use them across multiple tests. One way to do that is to parametrize your steps, for example: "Given I have created a level named ..", but the parameterization also introduces verbosity. I want to end up with something like Bryan Oakley suggests in his answer, but I just can't see how I can do that without creating steps which are very specific to each tests. This again means that I'll end up with a lot of steps which reduces maintainability. I looks like SpecFlow has some way of defining abbreviating steps by creating a file which inherits a base class called "Steps", but this still introduces new steps.
So to summarize things; show me a good approach for ending up with Bryan Oakleys answer which is maintainable.
I would simplify it to something like this:
Scenario: Add a new valve effect to a level
Given I have created a new level
When I add a new valve effect with the following values
| field name | value |
| Name | Effect123 |
Then I should get an on-screen confirmation that says "Effect added: Effect123"
The way I approached the problem was to imagine that you are completely redesigning the user interface. Would the test still be usable? For example, the test should work even if there is no "Add" button in the redesign, or you no longer user a popup window.
You could try wording them generically and use parameters.
Given i have create a new: Level
the ':' is only so you can identify the parameter. This means you would have one generic entry point for a step that needs to create a new something. Its up to the step then to look at the parameter of Level and create a new Level
Also try to come up with a naming conversion everyone can use. It should be easy to discover what steps have already been created so you don't get duplicate similar steps.
Can I suggest that maybe the code you are testing should go into unit tests. Maybe what you mean by "test specific" are individual unit tests that are not covered by your acceptance tests.
Just a thought :)
We have a requirement that every piece of code that makes it into production will be reviewed by a senior developer.
The way I have envisioned this working is by a naming convention for branches that regular developers cannot check code into.
Following the SVN recomended directory structure this translates into something like.
[project-name]/trunk/
[project-name]/branches/
[project-name]/branches/development-01
[project-name]/branches/development-02
[project-name]/branches/task-increasefontsize
[project-name]/branches/release-01
[project-name]/branches/release-02
[project-name]/tags/
So in the authz file I would like to have something like the following
[/]
#developers = rw
[/*/branches/release-*]
#developers = r
#senior_developers = rw
However I can't find any evidence that SVN supports * (or any other wildcard character).
Is such a thing possible or do I need a pre-commit hook?
It is possible to do a directory structure of
[project-name]/trunk/
[project-name]/branches/development-01
[project-name]/branches/development-02
[project-name]/branches/task-increasefontsize
[project-name]/branches/release-01
[project-name]/branches/release-02
[project-name]/tags/
[project-name]/releases/
and deny access to releases but that still leaves you having to do one denial listing per project and worse its not adhering to the SVN standard project structure.
It is not possible to have wildcards as you like to use them. For this purpose you should take a look at svnperm.py script (just google for it) it will match exactly this purpose.
I'm trying to figure out a way to find out which files were affected by a work item in TFS 2008.
I realize that this is a duplication of a question already asked by someone else here - View a list of all files changed as part of a Workitem in TFS but it went unanswered and I've been, off and on, looking for this for a while.
I understand can view the links tab of the work item and then view each changeset to see the files that have been changed. But, the work item very likely will end up with many changesets linked to it, and I would like to review the files modified as part of the work item, but I feel like the likelihood of missing a file or two is very high if I have to rely on looking at each of the 100+ changesets individually.
Does anyone know of a way to accomplish this? Thanks in advance for any help or guidance.
Sounds like a job for Powershell...
function Get-TfsItem([int] $workItemNumber)
{
Get-TfsServer njtfs -all |
foreach { $_.wit.GetWorkItem($workItemNumber) } |
foreach { $_.Links } |
foreach { ([regex]'vstfs:///VersionControl/Changeset/(\d+)').matches($_.LinkedArtifactUri) } |
foreach { $_.groups[1].value } |
Get-TfsChangeset |
Select-TfsItem |
Sort Path -Unique
}
The first several lines are kind of ugly. We have to hit the webservice API directly since the TFS cmdlets don't cover the bug tracking system. And the objects we get back require some regular expression love before they'll do what we need. Piping to "foreach" over & over is an unfortunate Powershell idiom that arises when you mate an unfriendly API to a lame projection operator. (I use my own replacement, personally, but you can't rely on that.)
The last 3 lines should be self explanatory if my TFS Power Cmdlets are installed & doing their job.
I just found Scrum Power Tools plugin for VS 2010 that does this with a button click in VSS, installed and it worked. http://visualstudiogallery.msdn.microsoft.com/3f261226-530e-4e9c-b7d7-451c2f77f262
I am just trying to make the powershell version 2010 work. http://msdn.microsoft.com/en-us/vstudio/bb980963
First problem is that the pwoer shell option is not installed by default, use custom install and select that option. When completed there is a powershell prompt in the TFS powertools 2010 menu, the commands only work in there.
The get server I had to replace njtfs with the url http://tfsserver:8080/tfs and remove -all. The script still fails.
Ultimately I need a detail report that lists:
source 'work item' 'change set'
For example:
xyz.cs 'work item 1' 'C397'
xyz.cs 'work item 2' 'C399'
Eventually I have to then work out that work item 1 is dependant on work item 2. I also have to track back to work item 1 to check the status.
Can someone assist with a 2010 version script? I have never written PS before.
I needed the exact same thing and I wrote a TFS utility for myself, using TFS API. It allows you to see all changes a work item triggered over time, and some things more. I've put it on codeplex. You can get it from:
tfshelper.codeplex.com