Test to determine if two genes/exons share the same evolutionary histories? In classic phylogenetic inference one is usually given various orthologue sequences of a given gene across various species. Those sequences are then multiple aligned and used to construct a phylogenetic tree.

Say, I split the multiple alignment of this gene into two parts (part A and B).
My question now is: What is the most appropriate test to determine if part A and B share the same phylogenetic history?

Having looked through literature, it appears this can be done by constructing phylogenetic trees separately for part A and B and test for incongruence using 


Kishino–Hasegawa (KH test); 
Shimodaira–Hasegawa (SH-test); 
SOWH-test etc. 


as nicely summarized in Plantet et all, and Goldman et al. etc.

However the above test rely on constructed trees beforehand which might be incorrect due to inappropriate algorithms/parameters. 

I was therefore wondering if there are more appropriate test maybe without having to construct trees at all?
Since there hasn't been any other answers, I'd thought to share my approach in case someone is having the same issue.

Gauging from the comments of tendon and NatWH, it seems using the SH-test valid stategy to tackle this problem.

Having done some research, I could only find one functional software package, the R-package phangorn which implements both, the SH- as well as SOWH-test and thought to share my R-workflow:



Reading in multiple-alignment (MLN). Here: amino-acids (AA)

 library(phangorn)
 mln &lt;- read.phyDat("my_mln.fasta", format = "fasta", type = "AA")


Partitioning MLN into two parts (part A and B) given a predefined breakpoint (here 100)

breakpoint &lt;- 100
 # partA: 1:breakpoing
 ( mln_partA &lt;- subset(mln, select = 1:breakpoint, site.pattern = FALSE) )
 # 58 sequences with 100 character and 45 different site patterns.
 # The states are a r n d c q e g h i l k m f p s t w y v

 ## partB: breakpoint:end
 ( mln_partB &lt;- subset(mln, select = (breakpoint + 1):length(attr(mln, "index")), site.pattern = FALSE) )
 # 58 sequences with 1702 character and 720 different site patterns.


Constructing tree(s) separately from part A and B using Neighbourhood Joining (NJ) method

 ## Note, other tree building algorithms might be used
 ( treeNJ_partA &lt;- NJ(dist.ml(mln_partA)) )
 # Phylogenetic tree with 58 tips and 56 internal nodes.
 # Unrooted; includes branch lengths.
 ( treeNJ_partB &lt;- NJ(dist.ml(mln_partB)) )
 # Phylogenetic tree with 58 tips and 56 internal nodes.
 # Unrooted; includes branch lengths.


Using topology of previously constructed trees and compute optimal likelihood based on partA data

 ( treeNJ_partA_fit1 &lt;- optim.pml(pml(treeNJ_partA, mln_partA)) )
 # optimize edge weights:  -1402.126 --&gt; -1379.043
 #
 #  loglikelihood: -1379.041
 #
 # unconstrained loglikelihood: -302.6292
 ( treeNJ_partB_fit1 &lt;- optim.pml(pml(treeNJ_partB, mln_partA)) )
 # optimize edge weights:  -1633.646 --&gt; -1530.745
 #
 #  loglikelihood: -1530.682
 #
 # unconstrained loglikelihood: -302.6292


Performing SH-test for for both trees

 ( shPart1_t12 &lt;- SH.test(treeNJ_partA_fit1, treeNJ_partB_fit1, data = mln_partA, B = 1e5) )
 #      Trees      ln L Diff ln L p-value
 # [1,]     1 -1379.041     0.000 0.48461
 # [2,]     2 -1530.682   151.641 0.00000


As can be seen in this example, the tree constructed for partB doesn't fit partA data as much as the tree constructed from partA.